diff options
author | Thomas Wouters <thomas@python.org> | 2006-04-21 10:40:58 (GMT) |
---|---|---|
committer | Thomas Wouters <thomas@python.org> | 2006-04-21 10:40:58 (GMT) |
commit | 49fd7fa4431da299196d74087df4a04f99f9c46f (patch) | |
tree | 35ace5fe78d3d52c7a9ab356ab9f6dbf8d4b71f4 /Tools | |
parent | 9ada3d6e29d5165dadacbe6be07bcd35cfbef59d (diff) | |
download | cpython-49fd7fa4431da299196d74087df4a04f99f9c46f.zip cpython-49fd7fa4431da299196d74087df4a04f99f9c46f.tar.gz cpython-49fd7fa4431da299196d74087df4a04f99f9c46f.tar.bz2 |
Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
number of tests, all because of the codecs/_multibytecodecs issue described
here (it's not a Py3K issue, just something Py3K discovers):
http://mail.python.org/pipermail/python-dev/2006-April/064051.html
Hye-Shik Chang promised to look for a fix, so no need to fix it here. The
tests that are expected to break are:
test_codecencodings_cn
test_codecencodings_hk
test_codecencodings_jp
test_codecencodings_kr
test_codecencodings_tw
test_codecs
test_multibytecodec
This merge fixes an actual test failure (test_weakref) in this branch,
though, so I believe merging is the right thing to do anyway.
Diffstat (limited to 'Tools')
40 files changed, 8407 insertions, 71 deletions
diff --git a/Tools/bgen/bgen/bgenObjectDefinition.py b/Tools/bgen/bgen/bgenObjectDefinition.py index a802f93..6f9bd53 100644 --- a/Tools/bgen/bgen/bgenObjectDefinition.py +++ b/Tools/bgen/bgen/bgenObjectDefinition.py @@ -383,6 +383,8 @@ class PEP253Mixin(PEP252Mixin): Output("%s_tp_free, /* tp_free */", self.prefix) def output_tp_initBody_basecall(self): + """If a type shares its init call with its base type set output_tp_initBody + to output_tp_initBody_basecall""" if self.basetype: Output("if (%s.tp_init)", self.basetype) OutLbrace() @@ -395,7 +397,6 @@ class PEP253Mixin(PEP252Mixin): if self.output_tp_initBody: Output("static int %s_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)", self.prefix) OutLbrace() - self.output_tp_initBody_basecall() self.output_tp_initBody() OutRbrace() else: @@ -425,7 +426,7 @@ class PEP253Mixin(PEP252Mixin): if self.basetype: Output("if (%s.tp_new)", self.basetype) OutLbrace() - Output("if ( (*%s.tp_init)(_self, _args, _kwds) == NULL) return NULL;", self.basetype) + Output("if ( (*%s.tp_new)(type, _args, _kwds) == NULL) return NULL;", self.basetype) Dedent() Output("} else {") Indent() diff --git a/Tools/buildbot/build.bat b/Tools/buildbot/build.bat index e3b77be..e96323c 100644 --- a/Tools/buildbot/build.bat +++ b/Tools/buildbot/build.bat @@ -1,4 +1,5 @@ @rem Used by the buildbot "compile" step. cmd /c Tools\buildbot\external.bat call "%VS71COMNTOOLS%vsvars32.bat" +cmd /q/c Tools\buildbot\kill_python.bat devenv.com /useenv /build Debug PCbuild\pcbuild.sln diff --git a/Tools/buildbot/external.bat b/Tools/buildbot/external.bat index 1b032ae..c6d252d 100644 --- a/Tools/buildbot/external.bat +++ b/Tools/buildbot/external.bat @@ -12,3 +12,24 @@ if not exist db-4.4.20 svn export http://svn.python.org/projects/external/db-4.4 if not exist db-4.4.20\build_win32\debug\libdb44sd.lib (
devenv db-4.4.20\build_win32\Berkeley_DB.sln /build Debug /project db_static
)
+
+@rem OpenSSL
+if not exist openssl-0.9.8a svn export http://svn.python.org/projects/external/openssl-0.9.8a
+
+@rem tcltk
+if not exist tcl8.4.12 (
+ if exist tcltk rd /s/q tcltk
+ svn export http://svn.python.org/projects/external/tcl8.4.12
+ svn export http://svn.python.org/projects/external/tk8.4.12
+ cd tcl8.4.12\win
+ nmake -f makefile.vc
+ nmake -f makefile.vc INSTALLDIR=..\..\tcltk install
+ cd ..\..
+ cd tk8.4.12\win
+ nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12
+ nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12 INSTALLDIR=..\..\tcltk install
+)
+
+@rem sqlite
+if not exist sqlite-source-3.3.4 svn export http://svn.python.org/projects/external/sqlite-source-3.3.4
+if not exist build\PCbuild\sqlite3.dll copy sqlite-source-3.3.4\sqlite3.dll build\PCbuild
diff --git a/Tools/buildbot/kill_python.bat b/Tools/buildbot/kill_python.bat new file mode 100644 index 0000000..d78b6d4 --- /dev/null +++ b/Tools/buildbot/kill_python.bat @@ -0,0 +1,3 @@ +cd Tools\buildbot +nmake /C /S /f kill_python.mak +kill_python.exe diff --git a/Tools/buildbot/kill_python.c b/Tools/buildbot/kill_python.c new file mode 100644 index 0000000..ebc9aa4 --- /dev/null +++ b/Tools/buildbot/kill_python.c @@ -0,0 +1,56 @@ +/* This program looks for processes which have build\PCbuild\python.exe + in their path and terminates them. */ +#include <windows.h> +#include <psapi.h> +#include <stdio.h> + +int main() +{ + DWORD pids[1024], cbNeeded; + int i, num_processes; + if (!EnumProcesses(pids, sizeof(pids), &cbNeeded)) { + printf("EnumProcesses failed\n"); + return 1; + } + num_processes = cbNeeded/sizeof(pids[0]); + for (i = 0; i < num_processes; i++) { + HANDLE hProcess; + char path[MAX_PATH]; + HMODULE mods[1024]; + int k, num_mods; + hProcess = OpenProcess(PROCESS_QUERY_INFORMATION + | PROCESS_VM_READ + | PROCESS_TERMINATE , + FALSE, pids[i]); + if (!hProcess) + /* process not accessible */ + continue; + if (!EnumProcessModules(hProcess, mods, sizeof(mods), &cbNeeded)) { + /* For unknown reasons, this sometimes returns ERROR_PARTIAL_COPY; + this apparently means we are not supposed to read the process. */ + if (GetLastError() == ERROR_PARTIAL_COPY) { + CloseHandle(hProcess); + continue; + } + printf("EnumProcessModules failed: %d\n", GetLastError()); + return 1; + } + if (!GetModuleFileNameEx(hProcess, NULL, path, sizeof(path))) { + printf("GetProcessImageFileName failed\n"); + return 1; + } + + _strlwr(path); + /* printf("%s\n", path); */ + if (strstr(path, "build\\pcbuild\\python_d.exe") != NULL) { + printf("Terminating %s (pid %d)\n", path, pids[i]); + if (!TerminateProcess(hProcess, 1)) { + printf("Termination failed: %d\n", GetLastError()); + return 1; + } + return 0; + } + + CloseHandle(hProcess); + } +} diff --git a/Tools/buildbot/kill_python.mak b/Tools/buildbot/kill_python.mak new file mode 100644 index 0000000..6027d3f --- /dev/null +++ b/Tools/buildbot/kill_python.mak @@ -0,0 +1,2 @@ +kill_python.exe: kill_python.c + cl -nologo -o kill_python.exe kill_python.c psapi.lib diff --git a/Tools/i18n/msgfmt.py b/Tools/i18n/msgfmt.py index b4ae3e9..6433131 100755 --- a/Tools/i18n/msgfmt.py +++ b/Tools/i18n/msgfmt.py @@ -127,7 +127,7 @@ def make(filename, outfile): section = None fuzzy = 0 # Record a fuzzy mark - if l[:2] == '#,' and l.find('fuzzy'): + if l[:2] == '#,' and 'fuzzy' in l: fuzzy = 1 # Skip comments if l[0] == '#': diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py index 6665d36..efa1696 100644 --- a/Tools/msi/msi.py +++ b/Tools/msi/msi.py @@ -6,6 +6,7 @@ from msilib import Feature, CAB, Directory, Dialog, Binary, add_data import uisample from win32com.client import constants from distutils.spawn import find_executable +from uuids import product_codes # Settings can be overridden in config.py below # 0 for official python.org releases @@ -23,6 +24,8 @@ srcdir = os.path.abspath("../..") full_current_version = None # Is Tcl available at all? have_tcl = True +# Where is sqlite3.dll located, relative to srcdir? +sqlite_dir = "../sqlite-source-3.3.4" try: from config import * @@ -62,30 +65,6 @@ current_version = "%s.%d" % (short_version, FIELD3) upgrade_code_snapshot='{92A24481-3ECB-40FC-8836-04B7966EC0D5}' upgrade_code='{65E6DE48-A358-434D-AA4F-4AF72DB4718F}' -# This should be extended for each Python release. -# The product code must change whenever the name of the MSI file -# changes, and when new component codes are issued for existing -# components. See "Changing the Product Code". As we change the -# component codes with every build, we need a new product code -# each time. For intermediate (snapshot) releases, they are automatically -# generated. For official releases, we record the product codes, -# so people can refer to them. -product_codes = { - '2.4.101': '{0e9b4d8e-6cda-446e-a208-7b92f3ddffa0}', # 2.4a1, released as a snapshot - '2.4.102': '{1b998745-4901-4edb-bc52-213689e1b922}', # 2.4a2 - '2.4.103': '{33fc8bd2-1e8f-4add-a40a-ade2728d5942}', # 2.4a3 - '2.4.111': '{51a7e2a8-2025-4ef0-86ff-e6aab742d1fa}', # 2.4b1 - '2.4.112': '{4a5e7c1d-c659-4fe3-b8c9-7c65bd9c95a5}', # 2.4b2 - '2.4.121': '{75508821-a8e9-40a8-95bd-dbe6033ddbea}', # 2.4c1 - '2.4.122': '{83a9118b-4bdd-473b-afc3-bcb142feca9e}', # 2.4c2 - '2.4.150': '{82d9302e-f209-4805-b548-52087047483a}', # 2.4.0 - '2.4.1121':'{be027411-8e6b-4440-a29b-b07df0690230}', # 2.4.1c1 - '2.4.1122':'{02818752-48bf-4074-a281-7a4114c4f1b1}', # 2.4.1c2 - '2.4.1150':'{4d4f5346-7e4a-40b5-9387-fdb6181357fc}', # 2.4.1 - '2.4.2121':'{5ef9d6b6-df78-45d2-ab09-14786a3c5a99}', # 2.4.2c1 - '2.4.2150':'{b191e49c-ea23-43b2-b28a-14e0784069b8}', # 2.4.2 -} - if snapshot: current_version = "%s.%s.%s" % (major, minor, int(time.time()/3600/24)) product_code = msilib.gen_uuid() @@ -109,14 +88,10 @@ extensions = [ '_tkinter.pyd', '_msi.pyd', '_ctypes.pyd', - '_ctypes_test.pyd' + '_ctypes_test.pyd', + '_sqlite3.pyd' ] -if major+minor <= "24": - extensions.extend([ - 'zlib.pyd', - ]) - # Well-known component UUIDs # These are needed for SharedDLLs reference counter; if # a different UUID was used for each incarnation of, say, @@ -392,7 +367,7 @@ def add_ui(db): ("VerdanaRed9", "Verdana", 9, 255, 0), ]) - compileargs = r"-Wi [TARGETDIR]Lib\compileall.py -f -x badsyntax [TARGETDIR]Lib" + compileargs = r"-Wi [TARGETDIR]Lib\compileall.py -f -x bad_coding|badsyntax|site-packages [TARGETDIR]Lib" # See "CustomAction Table" add_data(db, "CustomAction", [ # msidbCustomActionTypeFirstSequence + msidbCustomActionTypeTextData + msidbCustomActionTypeProperty @@ -491,7 +466,7 @@ def add_ui(db): c = exit_dialog.text("warning", 135, 200, 220, 40, 0x30003, "{\\VerdanaRed9}Warning: Python 2.5.x is the last " "Python release for Windows 9x.") - c.condition("Hide", "NOT Version9x") + c.condition("Hide", "NOT Version9X") exit_dialog.text("Description", 135, 235, 220, 20, 0x30003, "Click the Finish button to exit the Installer.") @@ -914,7 +889,7 @@ def add_files(db): continue tcltk.set_current() elif dir in ['test', 'tests', 'data', 'output']: - # test: Lib, Lib/email, Lib/bsddb + # test: Lib, Lib/email, Lib/bsddb, Lib/ctypes, Lib/sqlite3 # tests: Lib/distutils # data: Lib/email/test # output: Lib/test @@ -941,6 +916,8 @@ def add_files(db): lib.add_file("test.xml.out") lib.add_file("testtar.tar") lib.add_file("test_difflib_expect.html") + lib.add_file("check_soundcard.vbs") + lib.add_file("empty.vbs") lib.glob("*.uue") lib.add_file("readme.txt", src="README") if dir=='decimaltestdata': @@ -990,6 +967,14 @@ def add_files(db): tcldir = os.path.normpath(srcdir+"/../tcltk/bin") for f in glob.glob1(tcldir, "*.dll"): lib.add_file(f, src=os.path.join(tcldir, f)) + # Add sqlite + if msilib.msi_type=="Intel64;1033": + sqlite_arch = "/ia64" + elif msilib.msi_type=="x64;1033": + sqlite_arch = "/amd64" + else: + sqlite_arch = "" + lib.add_file(srcdir+"/"+sqlite_dir+sqlite_arch+"/sqlite3.dll") # check whether there are any unknown extensions for f in glob.glob1(srcdir+"/PCBuild", "*.pyd"): if f.endswith("_d.pyd"): continue # debug version diff --git a/Tools/msi/uuids.py b/Tools/msi/uuids.py new file mode 100644 index 0000000..ce7e604 --- /dev/null +++ b/Tools/msi/uuids.py @@ -0,0 +1,33 @@ +# This should be extended for each Python release. +# The product code must change whenever the name of the MSI file +# changes, and when new component codes are issued for existing +# components. See "Changing the Product Code". As we change the +# component codes with every build, we need a new product code +# each time. For intermediate (snapshot) releases, they are automatically +# generated. For official releases, we record the product codes, +# so people can refer to them. +product_codes = { + '2.4.101': '{0e9b4d8e-6cda-446e-a208-7b92f3ddffa0}', # 2.4a1, released as a snapshot + '2.4.102': '{1b998745-4901-4edb-bc52-213689e1b922}', # 2.4a2 + '2.4.103': '{33fc8bd2-1e8f-4add-a40a-ade2728d5942}', # 2.4a3 + '2.4.111': '{51a7e2a8-2025-4ef0-86ff-e6aab742d1fa}', # 2.4b1 + '2.4.112': '{4a5e7c1d-c659-4fe3-b8c9-7c65bd9c95a5}', # 2.4b2 + '2.4.121': '{75508821-a8e9-40a8-95bd-dbe6033ddbea}', # 2.4c1 + '2.4.122': '{83a9118b-4bdd-473b-afc3-bcb142feca9e}', # 2.4c2 + '2.4.150': '{82d9302e-f209-4805-b548-52087047483a}', # 2.4.0 + '2.4.1121':'{be027411-8e6b-4440-a29b-b07df0690230}', # 2.4.1c1 + '2.4.1122':'{02818752-48bf-4074-a281-7a4114c4f1b1}', # 2.4.1c2 + '2.4.1150':'{4d4f5346-7e4a-40b5-9387-fdb6181357fc}', # 2.4.1 + '2.4.2121':'{5ef9d6b6-df78-45d2-ab09-14786a3c5a99}', # 2.4.2c1 + '2.4.2150':'{b191e49c-ea23-43b2-b28a-14e0784069b8}', # 2.4.2 + '2.4.3121':'{f669ed4d-1dce-41c4-9617-d985397187a1}', # 2.4.3c1 + '2.4.3150':'{75e71add-042c-4f30-bfac-a9ec42351313}', # 2.4.3 + '2.5.101': '{bc14ce3e-5e72-4a64-ac1f-bf59a571898c}', # 2.5a1 + '2.5.102': '{5eed51c1-8e9d-4071-94c5-b40de5d49ba5}', # 2.5a2 + '2.5.103': '{73dcd966-ffec-415f-bb39-8342c1f47017}', # 2.5a3 + '2.5.111': '{c797ecf8-a8e6-4fec-bb99-526b65f28626}', # 2.5b1 + '2.5.112': '{32beb774-f625-439d-b587-7187487baf15}', # 2.5b2 + '2.5.121': '{8e9321bc-6b24-48a3-8fd4-c95f8e531e5f}', # 2.5c1 + '2.5.122': '{a6cd508d-9599-45da-a441-cbffa9f7e070}', # 2.5c2 + '2.5.150': '{0a2c5854-557e-48c8-835a-3b9f074bdcaa}', # 2.5.0 +} diff --git a/Tools/pybench/Arithmetic.py b/Tools/pybench/Arithmetic.py new file mode 100644 index 0000000..e95c30a --- /dev/null +++ b/Tools/pybench/Arithmetic.py @@ -0,0 +1,778 @@ +from pybench import Test + +class SimpleIntegerArithmetic(Test): + + version = 0.3 + operations = 5 * (3 + 5 + 5 + 3 + 3 + 3) + rounds = 120000 + + def test(self): + + for i in xrange(self.rounds): + + a = 2 + b = 3 + c = 3 + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2 + b = 3 + c = 3 + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2 + b = 3 + c = 3 + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2 + b = 3 + c = 3 + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2 + b = 3 + c = 3 + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + def calibrate(self): + + for i in xrange(self.rounds): + pass + +class SimpleFloatArithmetic(Test): + + version = 0.3 + operations = 5 * (3 + 5 + 5 + 3 + 3 + 3) + rounds = 100000 + + def test(self): + + for i in xrange(self.rounds): + + a = 2.1 + b = 3.3332 + c = 3.14159 + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2.1 + b = 3.3332 + c = 3.14159 + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2.1 + b = 3.3332 + c = 3.14159 + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2.1 + b = 3.3332 + c = 3.14159 + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2.1 + b = 3.3332 + c = 3.14159 + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + def calibrate(self): + + for i in xrange(self.rounds): + pass + +class SimpleIntFloatArithmetic(Test): + + version = 0.3 + operations = 5 * (3 + 5 + 5 + 3 + 3 + 3) + rounds = 120000 + + def test(self): + + for i in xrange(self.rounds): + + a = 2 + b = 3 + c = 3.14159 + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2 + b = 3 + c = 3.14159 + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2 + b = 3 + c = 3.14159 + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2 + b = 3 + c = 3.14159 + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2 + b = 3 + c = 3.14159 + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + def calibrate(self): + + for i in xrange(self.rounds): + pass + + +class SimpleLongArithmetic(Test): + + version = 0.3 + operations = 5 * (3 + 5 + 5 + 3 + 3 + 3) + rounds = 30000 + + def test(self): + + for i in xrange(self.rounds): + + a = 2220001L + b = 100001L + c = 30005L + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2220001L + b = 100001L + c = 30005L + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2220001L + b = 100001L + c = 30005L + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2220001L + b = 100001L + c = 30005L + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2220001L + b = 100001L + c = 30005L + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + def calibrate(self): + + for i in xrange(self.rounds): + pass + +class SimpleComplexArithmetic(Test): + + version = 0.3 + operations = 5 * (3 + 5 + 5 + 3 + 3 + 3) + rounds = 40000 + + def test(self): + + for i in xrange(self.rounds): + + a = 2 + 3j + b = 2.5 + 4.5j + c = 1.2 + 6.2j + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2 + 3j + b = 2.5 + 4.5j + c = 1.2 + 6.2j + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2 + 3j + b = 2.5 + 4.5j + c = 1.2 + 6.2j + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2 + 3j + b = 2.5 + 4.5j + c = 1.2 + 6.2j + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + a = 2 + 3j + b = 2.5 + 4.5j + c = 1.2 + 6.2j + + c = a + b + c = b + c + c = c + a + c = a + b + c = b + c + + c = c - a + c = a - b + c = b - c + c = c - a + c = b - c + + c = a / b + c = b / a + c = c / b + + c = a * b + c = b * a + c = c * b + + c = a / b + c = b / a + c = c / b + + def calibrate(self): + + for i in xrange(self.rounds): + pass + diff --git a/Tools/pybench/Calls.py b/Tools/pybench/Calls.py new file mode 100644 index 0000000..82e7a91 --- /dev/null +++ b/Tools/pybench/Calls.py @@ -0,0 +1,410 @@ +from pybench import Test + +class PythonFunctionCalls(Test): + + version = 0.3 + operations = 5*(1+4+4+2) + rounds = 60000 + + def test(self): + + global f,f1,g,h + + # define functions + def f(): + pass + + def f1(x): + pass + + def g(a,b,c): + return a,b,c + + def h(a,b,c,d=1,e=2,f=3): + return d,e,f + + # do calls + for i in xrange(self.rounds): + + f() + f1(i) + f1(i) + f1(i) + f1(i) + g(i,i,i) + g(i,i,i) + g(i,i,i) + g(i,i,i) + h(i,i,3,i,i) + h(i,i,i,2,i,3) + + f() + f1(i) + f1(i) + f1(i) + f1(i) + g(i,i,i) + g(i,i,i) + g(i,i,i) + g(i,i,i) + h(i,i,3,i,i) + h(i,i,i,2,i,3) + + f() + f1(i) + f1(i) + f1(i) + f1(i) + g(i,i,i) + g(i,i,i) + g(i,i,i) + g(i,i,i) + h(i,i,3,i,i) + h(i,i,i,2,i,3) + + f() + f1(i) + f1(i) + f1(i) + f1(i) + g(i,i,i) + g(i,i,i) + g(i,i,i) + g(i,i,i) + h(i,i,3,i,i) + h(i,i,i,2,i,3) + + f() + f1(i) + f1(i) + f1(i) + f1(i) + g(i,i,i) + g(i,i,i) + g(i,i,i) + g(i,i,i) + h(i,i,3,i,i) + h(i,i,i,2,i,3) + + def calibrate(self): + + global f,f1,g,h + + # define functions + def f(): + pass + + def f1(x): + pass + + def g(a,b,c): + return a,b,c + + def h(a,b,c,d=1,e=2,f=3): + return d,e,f + + # do calls + for i in xrange(self.rounds): + pass + +### + +class BuiltinFunctionCalls(Test): + + version = 0.4 + operations = 5*(2+5+5+5) + rounds = 30000 + + def test(self): + + # localize functions + f0 = globals + f1 = hash + f2 = cmp + f3 = range + + # do calls + for i in xrange(self.rounds): + + f0() + f0() + f1(i) + f1(i) + f1(i) + f1(i) + f1(i) + f2(1,2) + f2(1,2) + f2(1,2) + f2(1,2) + f2(1,2) + f3(1,3,2) + f3(1,3,2) + f3(1,3,2) + f3(1,3,2) + f3(1,3,2) + + f0() + f0() + f1(i) + f1(i) + f1(i) + f1(i) + f1(i) + f2(1,2) + f2(1,2) + f2(1,2) + f2(1,2) + f2(1,2) + f3(1,3,2) + f3(1,3,2) + f3(1,3,2) + f3(1,3,2) + f3(1,3,2) + + f0() + f0() + f1(i) + f1(i) + f1(i) + f1(i) + f1(i) + f2(1,2) + f2(1,2) + f2(1,2) + f2(1,2) + f2(1,2) + f3(1,3,2) + f3(1,3,2) + f3(1,3,2) + f3(1,3,2) + f3(1,3,2) + + f0() + f0() + f1(i) + f1(i) + f1(i) + f1(i) + f1(i) + f2(1,2) + f2(1,2) + f2(1,2) + f2(1,2) + f2(1,2) + f3(1,3,2) + f3(1,3,2) + f3(1,3,2) + f3(1,3,2) + f3(1,3,2) + + f0() + f0() + f1(i) + f1(i) + f1(i) + f1(i) + f1(i) + f2(1,2) + f2(1,2) + f2(1,2) + f2(1,2) + f2(1,2) + f3(1,3,2) + f3(1,3,2) + f3(1,3,2) + f3(1,3,2) + f3(1,3,2) + + def calibrate(self): + + # localize functions + f0 = dir + f1 = hash + f2 = range + f3 = range + + # do calls + for i in xrange(self.rounds): + pass + +### + +class PythonMethodCalls(Test): + + version = 0.3 + operations = 5*(6 + 5 + 4) + rounds = 20000 + + def test(self): + + class c: + + x = 2 + s = 'string' + + def f(self): + + return self.x + + def j(self,a,b): + + self.y = a + self.t = b + return self.y + + def k(self,a,b,c=3): + + self.y = a + self.s = b + self.t = c + + o = c() + + for i in xrange(self.rounds): + + o.f() + o.f() + o.f() + o.f() + o.f() + o.f() + o.j(i,i) + o.j(i,i) + o.j(i,2) + o.j(i,2) + o.j(2,2) + o.k(i,i) + o.k(i,2) + o.k(i,2,3) + o.k(i,i,c=4) + + o.f() + o.f() + o.f() + o.f() + o.f() + o.f() + o.j(i,i) + o.j(i,i) + o.j(i,2) + o.j(i,2) + o.j(2,2) + o.k(i,i) + o.k(i,2) + o.k(i,2,3) + o.k(i,i,c=4) + + o.f() + o.f() + o.f() + o.f() + o.f() + o.f() + o.j(i,i) + o.j(i,i) + o.j(i,2) + o.j(i,2) + o.j(2,2) + o.k(i,i) + o.k(i,2) + o.k(i,2,3) + o.k(i,i,c=4) + + o.f() + o.f() + o.f() + o.f() + o.f() + o.f() + o.j(i,i) + o.j(i,i) + o.j(i,2) + o.j(i,2) + o.j(2,2) + o.k(i,i) + o.k(i,2) + o.k(i,2,3) + o.k(i,i,c=4) + + o.f() + o.f() + o.f() + o.f() + o.f() + o.f() + o.j(i,i) + o.j(i,i) + o.j(i,2) + o.j(i,2) + o.j(2,2) + o.k(i,i) + o.k(i,2) + o.k(i,2,3) + o.k(i,i,c=4) + + def calibrate(self): + + class c: + + x = 2 + s = 'string' + + def f(self): + + return self.x + + def j(self,a,b): + + self.y = a + self.t = b + + def k(self,a,b,c=3): + + self.y = a + self.s = b + self.t = c + + o = c + + for i in xrange(self.rounds): + pass + +### + +class Recursion(Test): + + version = 0.3 + operations = 5 + rounds = 50000 + + def test(self): + + global f + + def f(x): + + if x > 1: + return f(x-1) + return 1 + + for i in xrange(self.rounds): + f(10) + f(10) + f(10) + f(10) + f(10) + + def calibrate(self): + + global f + + def f(x): + + if x > 0: + return f(x-1) + return 1 + + for i in xrange(self.rounds): + pass + diff --git a/Tools/pybench/CommandLine.py b/Tools/pybench/CommandLine.py new file mode 100644 index 0000000..fb7e07b --- /dev/null +++ b/Tools/pybench/CommandLine.py @@ -0,0 +1,634 @@ +""" CommandLine - Get and parse command line options + + NOTE: This still is very much work in progress !!! + + Different version are likely to be incompatible. + + TODO: + + * Incorporate the changes made by (see Inbox) + * Add number range option using srange() + +""" + +__copyright__ = """\ +Copyright (c), 1997-2006, Marc-Andre Lemburg (mal@lemburg.com) +Copyright (c), 2000-2006, eGenix.com Software GmbH (info@egenix.com) +See the documentation for further information on copyrights, +or contact the author. All Rights Reserved. +""" + +__version__ = '1.2' + +import sys, getopt, string, glob, os, re, exceptions, traceback + +### Helpers + +def _getopt_flags(options): + + """ Convert the option list to a getopt flag string and long opt + list + + """ + s = [] + l = [] + for o in options: + if o.prefix == '-': + # short option + s.append(o.name) + if o.takes_argument: + s.append(':') + else: + # long option + if o.takes_argument: + l.append(o.name+'=') + else: + l.append(o.name) + return string.join(s,''),l + +def invisible_input(prompt='>>> '): + + """ Get raw input from a terminal without echoing the characters to + the terminal, e.g. for password queries. + + """ + import getpass + entry = getpass.getpass(prompt) + if entry is None: + raise KeyboardInterrupt + return entry + +def fileopen(name, mode='wb', encoding=None): + + """ Open a file using mode. + + Default mode is 'wb' meaning to open the file for writing in + binary mode. If encoding is given, I/O to and from the file is + transparently encoded using the given encoding. + + Files opened for writing are chmod()ed to 0600. + + """ + if name == 'stdout': + return sys.stdout + elif name == 'stderr': + return sys.stderr + elif name == 'stdin': + return sys.stdin + else: + if encoding is not None: + import codecs + f = codecs.open(name, mode, encoding) + else: + f = open(name, mode) + if 'w' in mode: + os.chmod(name, 0600) + return f + +def option_dict(options): + + """ Return a dictionary mapping option names to Option instances. + """ + d = {} + for option in options: + d[option.name] = option + return d + +# Alias +getpasswd = invisible_input + +_integerRE = re.compile('\s*(-?\d+)\s*$') +_integerRangeRE = re.compile('\s*(-?\d+)\s*-\s*(-?\d+)\s*$') + +def srange(s, + + split=string.split,integer=_integerRE, + integerRange=_integerRangeRE): + + """ Converts a textual representation of integer numbers and ranges + to a Python list. + + Supported formats: 2,3,4,2-10,-1 - -3, 5 - -2 + + Values are appended to the created list in the order specified + in the string. + + """ + l = [] + append = l.append + for entry in split(s,','): + m = integer.match(entry) + if m: + append(int(m.groups()[0])) + continue + m = integerRange.match(entry) + if m: + start,end = map(int,m.groups()) + l[len(l):] = range(start,end+1) + return l + +def abspath(path, + + expandvars=os.path.expandvars,expanduser=os.path.expanduser, + join=os.path.join,getcwd=os.getcwd): + + """ Return the corresponding absolute path for path. + + path is expanded in the usual shell ways before + joining it with the current working directory. + + """ + try: + path = expandvars(path) + except AttributeError: + pass + try: + path = expanduser(path) + except AttributeError: + pass + return join(getcwd(), path) + +### Option classes + +class Option: + + """ Option base class. Takes no argument. + + """ + default = None + helptext = '' + prefix = '-' + takes_argument = 0 + has_default = 0 + tab = 15 + + def __init__(self,name,help=None): + + if not name[:1] == '-': + raise TypeError,'option names must start with "-"' + if name[1:2] == '-': + self.prefix = '--' + self.name = name[2:] + else: + self.name = name[1:] + if help: + self.help = help + + def __str__(self): + + o = self + name = o.prefix + o.name + if o.takes_argument: + name = name + ' arg' + if len(name) > self.tab: + name = name + '\n' + ' ' * (self.tab + 1 + len(o.prefix)) + else: + name = '%-*s ' % (self.tab, name) + description = o.help + if o.has_default: + description = description + ' (%s)' % o.default + return '%s %s' % (name, description) + +class ArgumentOption(Option): + + """ Option that takes an argument. + + An optional default argument can be given. + + """ + def __init__(self,name,help=None,default=None): + + # Basemethod + Option.__init__(self,name,help) + + if default is not None: + self.default = default + self.has_default = 1 + self.takes_argument = 1 + +class SwitchOption(Option): + + """ Options that can be on or off. Has an optional default value. + + """ + def __init__(self,name,help=None,default=None): + + # Basemethod + Option.__init__(self,name,help) + + if default is not None: + self.default = default + self.has_default = 1 + +### Application baseclass + +class Application: + + """ Command line application interface with builtin argument + parsing. + + """ + # Options the program accepts (Option instances) + options = [] + + # Standard settings; these are appended to options in __init__ + preset_options = [SwitchOption('-v', + 'generate verbose output'), + SwitchOption('-h', + 'show this help text'), + SwitchOption('--help', + 'show this help text'), + SwitchOption('--debug', + 'enable debugging'), + SwitchOption('--copyright', + 'show copyright'), + SwitchOption('--examples', + 'show examples of usage')] + + # The help layout looks like this: + # [header] - defaults to '' + # + # [synopsis] - formatted as '<self.name> %s' % self.synopsis + # + # options: + # [options] - formatted from self.options + # + # [version] - formatted as 'Version:\n %s' % self.version, if given + # + # [about] - defaults to '' + # + # Note: all fields that do not behave as template are formatted + # using the instances dictionary as substitution namespace, + # e.g. %(name)s will be replaced by the applications name. + # + + # Header (default to program name) + header = '' + + # Name (defaults to program name) + name = '' + + # Synopsis (%(name)s is replaced by the program name) + synopsis = '%(name)s [option] files...' + + # Version (optional) + version = '' + + # General information printed after the possible options (optional) + about = '' + + # Examples of usage to show when the --examples option is given (optional) + examples = '' + + # Copyright to show + copyright = __copyright__ + + # Apply file globbing ? + globbing = 1 + + # Generate debug output ? + debug = 0 + + # Generate verbose output ? + verbose = 0 + + # Internal errors to catch + InternalError = exceptions.Exception + + # Instance variables: + values = None # Dictionary of passed options (or default values) + # indexed by the options name, e.g. '-h' + files = None # List of passed filenames + optionlist = None # List of passed options + + def __init__(self,argv=None): + + # Setup application specs + if argv is None: + argv = sys.argv + self.filename = os.path.split(argv[0])[1] + if not self.name: + self.name = os.path.split(self.filename)[1] + else: + self.name = self.name + if not self.header: + self.header = self.name + else: + self.header = self.header + + # Init .arguments list + self.arguments = argv[1:] + + # Setup Option mapping + self.option_map = option_dict(self.options) + + # Append preset options + for option in self.preset_options: + if not self.option_map.has_key(option.name): + self.add_option(option) + + # Init .files list + self.files = [] + + # Start Application + try: + # Process startup + rc = self.startup() + if rc is not None: + raise SystemExit,rc + + # Parse command line + rc = self.parse() + if rc is not None: + raise SystemExit,rc + + # Start application + rc = self.main() + if rc is None: + rc = 0 + + except SystemExit,rc: + pass + + except KeyboardInterrupt: + print + print '* User Break' + print + rc = 1 + + except self.InternalError: + print + print '* Internal Error' + if self.debug: + print + traceback.print_exc(20, sys.stdout) + elif self.verbose: + print ' %s: %s' % sys.exc_info()[:2] + print + rc = 1 + + raise SystemExit,rc + + def add_option(self, option): + + """ Add a new Option instance to the Application dynamically. + + Note that this has to be done *before* .parse() is being + executed. + + """ + self.options.append(option) + self.option_map[option.name] = option + + def startup(self): + + """ Set user defined instance variables. + + If this method returns anything other than None, the + process is terminated with the return value as exit code. + + """ + return None + + def exit(self, rc=0): + + """ Exit the program. + + rc is used as exit code and passed back to the calling + program. It defaults to 0 which usually means: OK. + + """ + raise SystemExit, rc + + def parse(self): + + """ Parse the command line and fill in self.values and self.files. + + After having parsed the options, the remaining command line + arguments are interpreted as files and passed to .handle_files() + for processing. + + As final step the option handlers are called in the order + of the options given on the command line. + + """ + # Parse arguments + self.values = values = {} + for o in self.options: + if o.has_default: + values[o.prefix+o.name] = o.default + else: + values[o.prefix+o.name] = 0 + flags,lflags = _getopt_flags(self.options) + try: + optlist,files = getopt.getopt(self.arguments,flags,lflags) + if self.globbing: + l = [] + for f in files: + gf = glob.glob(f) + if not gf: + l.append(f) + else: + l[len(l):] = gf + files = l + self.optionlist = optlist + self.files = files + self.files + except getopt.error,why: + self.help(why) + sys.exit(1) + + # Call file handler + rc = self.handle_files(self.files) + if rc is not None: + sys.exit(rc) + + # Call option handlers + for optionname, value in optlist: + + # Try to convert value to integer + try: + value = string.atoi(value) + except ValueError: + pass + + # Find handler and call it (or count the number of option + # instances on the command line) + handlername = 'handle' + string.replace(optionname, '-', '_') + try: + handler = getattr(self, handlername) + except AttributeError: + if value == '': + # count the number of occurances + if values.has_key(optionname): + values[optionname] = values[optionname] + 1 + else: + values[optionname] = 1 + else: + values[optionname] = value + else: + rc = handler(value) + if rc is not None: + raise SystemExit, rc + + # Apply final file check (for backward compatibility) + rc = self.check_files(self.files) + if rc is not None: + sys.exit(rc) + + def check_files(self,filelist): + + """ Apply some user defined checks on the files given in filelist. + + This may modify filelist in place. A typical application + is checking that at least n files are given. + + If this method returns anything other than None, the + process is terminated with the return value as exit code. + + """ + return None + + def help(self,note=''): + + self.print_header() + if self.synopsis: + print 'Synopsis:' + # To remain backward compatible: + try: + synopsis = self.synopsis % self.name + except (NameError, KeyError, TypeError): + synopsis = self.synopsis % self.__dict__ + print ' ' + synopsis + print + self.print_options() + if self.version: + print 'Version:' + print ' %s' % self.version + print + if self.about: + print string.strip(self.about % self.__dict__) + print + if note: + print '-'*72 + print 'Note:',note + print + + def notice(self,note): + + print '-'*72 + print 'Note:',note + print '-'*72 + print + + def print_header(self): + + print '-'*72 + print self.header % self.__dict__ + print '-'*72 + print + + def print_options(self): + + options = self.options + print 'Options and default settings:' + if not options: + print ' None' + return + long = filter(lambda x: x.prefix == '--', options) + short = filter(lambda x: x.prefix == '-', options) + items = short + long + for o in options: + print ' ',o + print + + # + # Example handlers: + # + # If a handler returns anything other than None, processing stops + # and the return value is passed to sys.exit() as argument. + # + + # File handler + def handle_files(self,files): + + """ This may process the files list in place. + """ + return None + + # Short option handler + def handle_h(self,arg): + + self.help() + return 0 + + def handle_v(self, value): + + """ Turn on verbose output. + """ + self.verbose = 1 + + # Handlers for long options have two underscores in their name + def handle__help(self,arg): + + self.help() + return 0 + + def handle__debug(self,arg): + + self.debug = 1 + # We don't want to catch internal errors: + self.InternalError = None + + def handle__copyright(self,arg): + + self.print_header() + print string.strip(self.copyright % self.__dict__) + print + return 0 + + def handle__examples(self,arg): + + self.print_header() + if self.examples: + print 'Examples:' + print + print string.strip(self.examples % self.__dict__) + print + else: + print 'No examples available.' + print + return 0 + + def main(self): + + """ Override this method as program entry point. + + The return value is passed to sys.exit() as argument. If + it is None, 0 is assumed (meaning OK). Unhandled + exceptions are reported with exit status code 1 (see + __init__ for further details). + + """ + return None + +# Alias +CommandLine = Application + +def _test(): + + class MyApplication(Application): + header = 'Test Application' + version = __version__ + options = [Option('-v','verbose')] + + def handle_v(self,arg): + print 'VERBOSE, Yeah !' + + cmd = MyApplication() + if not cmd.values['-h']: + cmd.help() + print 'files:',cmd.files + print 'Bye...' + +if __name__ == '__main__': + _test() diff --git a/Tools/pybench/Constructs.py b/Tools/pybench/Constructs.py new file mode 100644 index 0000000..aba888f --- /dev/null +++ b/Tools/pybench/Constructs.py @@ -0,0 +1,565 @@ +from pybench import Test + +class IfThenElse(Test): + + version = 0.31 + operations = 30*3 # hard to say... + rounds = 150000 + + def test(self): + + a,b,c = 1,2,3 + for i in xrange(self.rounds): + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + if a == 1: + if b == 2: + if c != 3: + c = 3 + b = 3 + else: + c = 2 + elif b == 3: + b = 2 + a = 2 + elif a == 2: + a = 3 + else: + a = 1 + + def calibrate(self): + + a,b,c = 1,2,3 + for i in xrange(self.rounds): + pass + +class NestedForLoops(Test): + + version = 0.3 + operations = 1000*10*5 + rounds = 150 + + def test(self): + + l1 = range(1000) + l2 = range(10) + l3 = range(5) + for i in xrange(self.rounds): + for i in l1: + for j in l2: + for k in l3: + pass + + def calibrate(self): + + l1 = range(1000) + l2 = range(10) + l3 = range(5) + for i in xrange(self.rounds): + pass + +class ForLoops(Test): + + version = 0.1 + operations = 5 * 5 + rounds = 8000 + + def test(self): + + l1 = range(100) + for i in xrange(self.rounds): + for i in l1: + pass + for i in l1: + pass + for i in l1: + pass + for i in l1: + pass + for i in l1: + pass + + for i in l1: + pass + for i in l1: + pass + for i in l1: + pass + for i in l1: + pass + for i in l1: + pass + + for i in l1: + pass + for i in l1: + pass + for i in l1: + pass + for i in l1: + pass + for i in l1: + pass + + for i in l1: + pass + for i in l1: + pass + for i in l1: + pass + for i in l1: + pass + for i in l1: + pass + + for i in l1: + pass + for i in l1: + pass + for i in l1: + pass + for i in l1: + pass + for i in l1: + pass + + def calibrate(self): + + l1 = range(1000) + for i in xrange(self.rounds): + pass + diff --git a/Tools/pybench/Dict.py b/Tools/pybench/Dict.py new file mode 100644 index 0000000..207d88f --- /dev/null +++ b/Tools/pybench/Dict.py @@ -0,0 +1,503 @@ +from pybench import Test + +class DictCreation(Test): + + version = 0.3 + operations = 5*(5 + 5) + rounds = 60000 + + def test(self): + + for i in xrange(self.rounds): + + d1 = {} + d2 = {} + d3 = {} + d4 = {} + d5 = {} + + d1 = {1:2,3:4,5:6} + d2 = {2:3,4:5,6:7} + d3 = {3:4,5:6,7:8} + d4 = {4:5,6:7,8:9} + d5 = {6:7,8:9,10:11} + + d1 = {} + d2 = {} + d3 = {} + d4 = {} + d5 = {} + + d1 = {1:2,3:4,5:6} + d2 = {2:3,4:5,6:7} + d3 = {3:4,5:6,7:8} + d4 = {4:5,6:7,8:9} + d5 = {6:7,8:9,10:11} + + d1 = {} + d2 = {} + d3 = {} + d4 = {} + d5 = {} + + d1 = {1:2,3:4,5:6} + d2 = {2:3,4:5,6:7} + d3 = {3:4,5:6,7:8} + d4 = {4:5,6:7,8:9} + d5 = {6:7,8:9,10:11} + + d1 = {} + d2 = {} + d3 = {} + d4 = {} + d5 = {} + + d1 = {1:2,3:4,5:6} + d2 = {2:3,4:5,6:7} + d3 = {3:4,5:6,7:8} + d4 = {4:5,6:7,8:9} + d5 = {6:7,8:9,10:11} + + d1 = {} + d2 = {} + d3 = {} + d4 = {} + d5 = {} + + d1 = {1:2,3:4,5:6} + d2 = {2:3,4:5,6:7} + d3 = {3:4,5:6,7:8} + d4 = {4:5,6:7,8:9} + d5 = {6:7,8:9,10:11} + + def calibrate(self): + + for i in xrange(self.rounds): + pass + +class DictWithStringKeys(Test): + + version = 0.1 + operations = 5*(6 + 6) + rounds = 200000 + + def test(self): + + d = {} + + for i in xrange(self.rounds): + + d['abc'] = 1 + d['def'] = 2 + d['ghi'] = 3 + d['jkl'] = 4 + d['mno'] = 5 + d['pqr'] = 6 + + d['abc'] + d['def'] + d['ghi'] + d['jkl'] + d['mno'] + d['pqr'] + + d['abc'] = 1 + d['def'] = 2 + d['ghi'] = 3 + d['jkl'] = 4 + d['mno'] = 5 + d['pqr'] = 6 + + d['abc'] + d['def'] + d['ghi'] + d['jkl'] + d['mno'] + d['pqr'] + + d['abc'] = 1 + d['def'] = 2 + d['ghi'] = 3 + d['jkl'] = 4 + d['mno'] = 5 + d['pqr'] = 6 + + d['abc'] + d['def'] + d['ghi'] + d['jkl'] + d['mno'] + d['pqr'] + + d['abc'] = 1 + d['def'] = 2 + d['ghi'] = 3 + d['jkl'] = 4 + d['mno'] = 5 + d['pqr'] = 6 + + d['abc'] + d['def'] + d['ghi'] + d['jkl'] + d['mno'] + d['pqr'] + + d['abc'] = 1 + d['def'] = 2 + d['ghi'] = 3 + d['jkl'] = 4 + d['mno'] = 5 + d['pqr'] = 6 + + d['abc'] + d['def'] + d['ghi'] + d['jkl'] + d['mno'] + d['pqr'] + + def calibrate(self): + + d = {} + + for i in xrange(self.rounds): + pass + +class DictWithFloatKeys(Test): + + version = 0.1 + operations = 5*(6 + 6) + rounds = 200000 + + def test(self): + + d = {} + + for i in xrange(self.rounds): + + d[1.234] = 1 + d[2.345] = 2 + d[3.456] = 3 + d[4.567] = 4 + d[5.678] = 5 + d[6.789] = 6 + + d[1.234] + d[2.345] + d[3.456] + d[4.567] + d[5.678] + d[6.789] + + d[1.234] = 1 + d[2.345] = 2 + d[3.456] = 3 + d[4.567] = 4 + d[5.678] = 5 + d[6.789] = 6 + + d[1.234] + d[2.345] + d[3.456] + d[4.567] + d[5.678] + d[6.789] + + d[1.234] = 1 + d[2.345] = 2 + d[3.456] = 3 + d[4.567] = 4 + d[5.678] = 5 + d[6.789] = 6 + + d[1.234] + d[2.345] + d[3.456] + d[4.567] + d[5.678] + d[6.789] + + d[1.234] = 1 + d[2.345] = 2 + d[3.456] = 3 + d[4.567] = 4 + d[5.678] = 5 + d[6.789] = 6 + + d[1.234] + d[2.345] + d[3.456] + d[4.567] + d[5.678] + d[6.789] + + d[1.234] = 1 + d[2.345] = 2 + d[3.456] = 3 + d[4.567] = 4 + d[5.678] = 5 + d[6.789] = 6 + + d[1.234] + d[2.345] + d[3.456] + d[4.567] + d[5.678] + d[6.789] + + def calibrate(self): + + d = {} + + for i in xrange(self.rounds): + pass + +class DictWithIntegerKeys(Test): + + version = 0.1 + operations = 5*(6 + 6) + rounds = 200000 + + def test(self): + + d = {} + + for i in xrange(self.rounds): + + d[1] = 1 + d[2] = 2 + d[3] = 3 + d[4] = 4 + d[5] = 5 + d[6] = 6 + + d[1] + d[2] + d[3] + d[4] + d[5] + d[6] + + d[1] = 1 + d[2] = 2 + d[3] = 3 + d[4] = 4 + d[5] = 5 + d[6] = 6 + + d[1] + d[2] + d[3] + d[4] + d[5] + d[6] + + d[1] = 1 + d[2] = 2 + d[3] = 3 + d[4] = 4 + d[5] = 5 + d[6] = 6 + + d[1] + d[2] + d[3] + d[4] + d[5] + d[6] + + d[1] = 1 + d[2] = 2 + d[3] = 3 + d[4] = 4 + d[5] = 5 + d[6] = 6 + + d[1] + d[2] + d[3] + d[4] + d[5] + d[6] + + d[1] = 1 + d[2] = 2 + d[3] = 3 + d[4] = 4 + d[5] = 5 + d[6] = 6 + + d[1] + d[2] + d[3] + d[4] + d[5] + d[6] + + def calibrate(self): + + d = {} + + for i in xrange(self.rounds): + pass + +class SimpleDictManipulation(Test): + + version = 0.3 + operations = 5*(6 + 6 + 6 + 6) + rounds = 50000 + + def test(self): + + d = {} + + for i in xrange(self.rounds): + + d[0] = 3 + d[1] = 4 + d[2] = 5 + d[3] = 3 + d[4] = 4 + d[5] = 5 + + x = d[0] + x = d[1] + x = d[2] + x = d[3] + x = d[4] + x = d[5] + + d.has_key(0) + d.has_key(2) + d.has_key(4) + d.has_key(6) + d.has_key(8) + d.has_key(10) + + del d[0] + del d[1] + del d[2] + del d[3] + del d[4] + del d[5] + + d[0] = 3 + d[1] = 4 + d[2] = 5 + d[3] = 3 + d[4] = 4 + d[5] = 5 + + x = d[0] + x = d[1] + x = d[2] + x = d[3] + x = d[4] + x = d[5] + + d.has_key(0) + d.has_key(2) + d.has_key(4) + d.has_key(6) + d.has_key(8) + d.has_key(10) + + del d[0] + del d[1] + del d[2] + del d[3] + del d[4] + del d[5] + + d[0] = 3 + d[1] = 4 + d[2] = 5 + d[3] = 3 + d[4] = 4 + d[5] = 5 + + x = d[0] + x = d[1] + x = d[2] + x = d[3] + x = d[4] + x = d[5] + + d.has_key(0) + d.has_key(2) + d.has_key(4) + d.has_key(6) + d.has_key(8) + d.has_key(10) + + del d[0] + del d[1] + del d[2] + del d[3] + del d[4] + del d[5] + + d[0] = 3 + d[1] = 4 + d[2] = 5 + d[3] = 3 + d[4] = 4 + d[5] = 5 + + x = d[0] + x = d[1] + x = d[2] + x = d[3] + x = d[4] + x = d[5] + + d.has_key(0) + d.has_key(2) + d.has_key(4) + d.has_key(6) + d.has_key(8) + d.has_key(10) + + del d[0] + del d[1] + del d[2] + del d[3] + del d[4] + del d[5] + + d[0] = 3 + d[1] = 4 + d[2] = 5 + d[3] = 3 + d[4] = 4 + d[5] = 5 + + x = d[0] + x = d[1] + x = d[2] + x = d[3] + x = d[4] + x = d[5] + + d.has_key(0) + d.has_key(2) + d.has_key(4) + d.has_key(6) + d.has_key(8) + d.has_key(10) + + del d[0] + del d[1] + del d[2] + del d[3] + del d[4] + del d[5] + + def calibrate(self): + + d = {} + + for i in xrange(self.rounds): + pass + diff --git a/Tools/pybench/Exceptions.py b/Tools/pybench/Exceptions.py new file mode 100644 index 0000000..295c83a --- /dev/null +++ b/Tools/pybench/Exceptions.py @@ -0,0 +1,681 @@ +from pybench import Test + +class TryRaiseExcept(Test): + + version = 0.1 + operations = 2 + 3 + rounds = 60000 + + def test(self): + + error = ValueError + + for i in xrange(self.rounds): + try: + raise error + except: + pass + try: + raise error + except: + pass + try: + raise error,"something" + except: + pass + try: + raise error,"something" + except: + pass + try: + raise error,"something" + except: + pass + + def calibrate(self): + + error = ValueError + + for i in xrange(self.rounds): + pass + + +class TryExcept(Test): + + version = 0.1 + operations = 15 * 10 + rounds = 200000 + + def test(self): + + for i in xrange(self.rounds): + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + + + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + + + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + + + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + + + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + + + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + + + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + + + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + + + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + + + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + try: + pass + except: + pass + + def calibrate(self): + + for i in xrange(self.rounds): + pass + + diff --git a/Tools/pybench/Imports.py b/Tools/pybench/Imports.py new file mode 100644 index 0000000..eb458b4 --- /dev/null +++ b/Tools/pybench/Imports.py @@ -0,0 +1,139 @@ +from pybench import Test + +# First imports: +import os +import package.submodule + +class SecondImport(Test): + + version = 0.1 + operations = 5 * 5 + rounds = 20000 + + def test(self): + + for i in xrange(self.rounds): + import os + import os + import os + import os + import os + + import os + import os + import os + import os + import os + + import os + import os + import os + import os + import os + + import os + import os + import os + import os + import os + + import os + import os + import os + import os + import os + + def calibrate(self): + + for i in xrange(self.rounds): + pass + + +class SecondPackageImport(Test): + + version = 0.1 + operations = 5 * 5 + rounds = 20000 + + def test(self): + + for i in xrange(self.rounds): + import package + import package + import package + import package + import package + + import package + import package + import package + import package + import package + + import package + import package + import package + import package + import package + + import package + import package + import package + import package + import package + + import package + import package + import package + import package + import package + + def calibrate(self): + + for i in xrange(self.rounds): + pass + +class SecondSubmoduleImport(Test): + + version = 0.1 + operations = 5 * 5 + rounds = 20000 + + def test(self): + + for i in xrange(self.rounds): + import package.submodule + import package.submodule + import package.submodule + import package.submodule + import package.submodule + + import package.submodule + import package.submodule + import package.submodule + import package.submodule + import package.submodule + + import package.submodule + import package.submodule + import package.submodule + import package.submodule + import package.submodule + + import package.submodule + import package.submodule + import package.submodule + import package.submodule + import package.submodule + + import package.submodule + import package.submodule + import package.submodule + import package.submodule + import package.submodule + + def calibrate(self): + + for i in xrange(self.rounds): + pass + diff --git a/Tools/pybench/Instances.py b/Tools/pybench/Instances.py new file mode 100644 index 0000000..7663e23 --- /dev/null +++ b/Tools/pybench/Instances.py @@ -0,0 +1,68 @@ +from pybench import Test + +class CreateInstances(Test): + + version = 0.2 + operations = 3 + 7 + 4 + rounds = 60000 + + def test(self): + + class c: + pass + + class d: + def __init__(self,a,b,c): + self.a = a + self.b = b + self.c = c + + class e: + def __init__(self,a,b,c=4): + self.a = a + self.b = b + self.c = c + self.d = a + self.e = b + self.f = c + + for i in xrange(self.rounds): + o = c() + o1 = c() + o2 = c() + p = d(i,i,3) + p1 = d(i,i,3) + p2 = d(i,3,3) + p3 = d(3,i,3) + p4 = d(i,i,i) + p5 = d(3,i,3) + p6 = d(i,i,i) + q = e(i,i,3) + q1 = e(i,i,3) + q2 = e(i,i,3) + q3 = e(i,i) + + def calibrate(self): + + class c: + pass + + class d: + def __init__(self,a,b,c): + self.a = a + self.b = b + self.c = c + + class e: + def __init__(self,a,b,c=4): + self.a = a + self.b = b + self.c = c + self.d = a + self.e = b + self.f = c + + for i in xrange(self.rounds): + pass + + diff --git a/Tools/pybench/LICENSE b/Tools/pybench/LICENSE new file mode 100644 index 0000000..17c6a6b --- /dev/null +++ b/Tools/pybench/LICENSE @@ -0,0 +1,25 @@ +pybench License +--------------- + +This copyright notice and license applies to all files in the pybench +directory of the pybench distribution. + +Copyright (c), 1997-2006, Marc-Andre Lemburg (mal@lemburg.com) +Copyright (c), 2000-2006, eGenix.com Software GmbH (info@egenix.com) + + All Rights Reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee or royalty is hereby +granted, provided that the above copyright notice appear in all copies +and that both that copyright notice and this permission notice appear +in supporting documentation or portions thereof, including +modifications, that you make. + +THE AUTHOR MARC-ANDRE LEMBURG DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, +INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING +FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE ! diff --git a/Tools/pybench/Lists.py b/Tools/pybench/Lists.py new file mode 100644 index 0000000..a06b44c --- /dev/null +++ b/Tools/pybench/Lists.py @@ -0,0 +1,292 @@ +from pybench import Test + +class SimpleListManipulation(Test): + + version = 0.3 + operations = 5* (6 + 6 + 6) + rounds = 60000 + + def test(self): + + l = [] + + for i in xrange(self.rounds): + + l.append(2) + l.append(3) + l.append(4) + l.append(2) + l.append(3) + l.append(4) + + l[0] = 3 + l[1] = 4 + l[2] = 5 + l[3] = 3 + l[4] = 4 + l[5] = 5 + + x = l[0] + x = l[1] + x = l[2] + x = l[3] + x = l[4] + x = l[5] + + l.append(2) + l.append(3) + l.append(4) + l.append(2) + l.append(3) + l.append(4) + + l[0] = 3 + l[1] = 4 + l[2] = 5 + l[3] = 3 + l[4] = 4 + l[5] = 5 + + x = l[0] + x = l[1] + x = l[2] + x = l[3] + x = l[4] + x = l[5] + + l.append(2) + l.append(3) + l.append(4) + l.append(2) + l.append(3) + l.append(4) + + l[0] = 3 + l[1] = 4 + l[2] = 5 + l[3] = 3 + l[4] = 4 + l[5] = 5 + + x = l[0] + x = l[1] + x = l[2] + x = l[3] + x = l[4] + x = l[5] + + l.append(2) + l.append(3) + l.append(4) + l.append(2) + l.append(3) + l.append(4) + + l[0] = 3 + l[1] = 4 + l[2] = 5 + l[3] = 3 + l[4] = 4 + l[5] = 5 + + x = l[0] + x = l[1] + x = l[2] + x = l[3] + x = l[4] + x = l[5] + + l.append(2) + l.append(3) + l.append(4) + l.append(2) + l.append(3) + l.append(4) + + l[0] = 3 + l[1] = 4 + l[2] = 5 + l[3] = 3 + l[4] = 4 + l[5] = 5 + + x = l[0] + x = l[1] + x = l[2] + x = l[3] + x = l[4] + x = l[5] + + if len(l) > 10000: + # cut down the size + del l[:] + + def calibrate(self): + + l = [] + + for i in xrange(self.rounds): + pass + +class ListSlicing(Test): + + version = 0.4 + operations = 25*(3+1+2+1) + rounds = 400 + + def test(self): + + n = range(100) + r = range(25) + + for i in xrange(self.rounds): + + l = range(100) + + for j in r: + + m = l[50:] + m = l[:25] + m = l[50:55] + l[:3] = n + m = l[:-1] + m = l[1:] + l[-1:] = n + + def calibrate(self): + + n = range(100) + r = range(25) + + for i in xrange(self.rounds): + + l = range(100) + + for j in r: + pass + +class SmallLists(Test): + + version = 0.3 + operations = 5*(1+ 6 + 6 + 3 + 1) + rounds = 60000 + + def test(self): + + for i in xrange(self.rounds): + + l = [] + + l.append(2) + l.append(3) + l.append(4) + l.append(2) + l.append(3) + l.append(4) + + l[0] = 3 + l[1] = 4 + l[2] = 5 + l[3] = 3 + l[4] = 4 + l[5] = 5 + + l[:3] = [1,2,3] + m = l[:-1] + m = l[1:] + + l[-1:] = [4,5,6] + + l = [] + + l.append(2) + l.append(3) + l.append(4) + l.append(2) + l.append(3) + l.append(4) + + l[0] = 3 + l[1] = 4 + l[2] = 5 + l[3] = 3 + l[4] = 4 + l[5] = 5 + + l[:3] = [1,2,3] + m = l[:-1] + m = l[1:] + + l[-1:] = [4,5,6] + + l = [] + + l.append(2) + l.append(3) + l.append(4) + l.append(2) + l.append(3) + l.append(4) + + l[0] = 3 + l[1] = 4 + l[2] = 5 + l[3] = 3 + l[4] = 4 + l[5] = 5 + + l[:3] = [1,2,3] + m = l[:-1] + m = l[1:] + + l[-1:] = [4,5,6] + + l = [] + + l.append(2) + l.append(3) + l.append(4) + l.append(2) + l.append(3) + l.append(4) + + l[0] = 3 + l[1] = 4 + l[2] = 5 + l[3] = 3 + l[4] = 4 + l[5] = 5 + + l[:3] = [1,2,3] + m = l[:-1] + m = l[1:] + + l[-1:] = [4,5,6] + + l = [] + + l.append(2) + l.append(3) + l.append(4) + l.append(2) + l.append(3) + l.append(4) + + l[0] = 3 + l[1] = 4 + l[2] = 5 + l[3] = 3 + l[4] = 4 + l[5] = 5 + + l[:3] = [1,2,3] + m = l[:-1] + m = l[1:] + + l[-1:] = [4,5,6] + + def calibrate(self): + + for i in xrange(self.rounds): + l = [] + diff --git a/Tools/pybench/Lookups.py b/Tools/pybench/Lookups.py new file mode 100644 index 0000000..fbbc0ed --- /dev/null +++ b/Tools/pybench/Lookups.py @@ -0,0 +1,946 @@ +from pybench import Test + +class SpecialClassAttribute(Test): + + version = 0.3 + operations = 5*(12 + 12) + rounds = 100000 + + def test(self): + + class c: + pass + + for i in xrange(self.rounds): + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + x = c.__a + x = c.__b + x = c.__c + + x = c.__a + x = c.__b + x = c.__c + + x = c.__a + x = c.__b + x = c.__c + + x = c.__a + x = c.__b + x = c.__c + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + x = c.__a + x = c.__b + x = c.__c + + x = c.__a + x = c.__b + x = c.__c + + x = c.__a + x = c.__b + x = c.__c + + x = c.__a + x = c.__b + x = c.__c + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + x = c.__a + x = c.__b + x = c.__c + + x = c.__a + x = c.__b + x = c.__c + + x = c.__a + x = c.__b + x = c.__c + + x = c.__a + x = c.__b + x = c.__c + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + x = c.__a + x = c.__b + x = c.__c + + x = c.__a + x = c.__b + x = c.__c + + x = c.__a + x = c.__b + x = c.__c + + x = c.__a + x = c.__b + x = c.__c + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + c.__a = 2 + c.__b = 3 + c.__c = 4 + + x = c.__a + x = c.__b + x = c.__c + + x = c.__a + x = c.__b + x = c.__c + + x = c.__a + x = c.__b + x = c.__c + + x = c.__a + x = c.__b + x = c.__c + + def calibrate(self): + + class c: + pass + + for i in xrange(self.rounds): + pass + +class NormalClassAttribute(Test): + + version = 0.3 + operations = 5*(12 + 12) + rounds = 100000 + + def test(self): + + class c: + pass + + for i in xrange(self.rounds): + + c.a = 2 + c.b = 3 + c.c = 4 + + c.a = 2 + c.b = 3 + c.c = 4 + + c.a = 2 + c.b = 3 + c.c = 4 + + c.a = 2 + c.b = 3 + c.c = 4 + + + x = c.a + x = c.b + x = c.c + + x = c.a + x = c.b + x = c.c + + x = c.a + x = c.b + x = c.c + + x = c.a + x = c.b + x = c.c + + c.a = 2 + c.b = 3 + c.c = 4 + + c.a = 2 + c.b = 3 + c.c = 4 + + c.a = 2 + c.b = 3 + c.c = 4 + + c.a = 2 + c.b = 3 + c.c = 4 + + + x = c.a + x = c.b + x = c.c + + x = c.a + x = c.b + x = c.c + + x = c.a + x = c.b + x = c.c + + x = c.a + x = c.b + x = c.c + + c.a = 2 + c.b = 3 + c.c = 4 + + c.a = 2 + c.b = 3 + c.c = 4 + + c.a = 2 + c.b = 3 + c.c = 4 + + c.a = 2 + c.b = 3 + c.c = 4 + + + x = c.a + x = c.b + x = c.c + + x = c.a + x = c.b + x = c.c + + x = c.a + x = c.b + x = c.c + + x = c.a + x = c.b + x = c.c + + c.a = 2 + c.b = 3 + c.c = 4 + + c.a = 2 + c.b = 3 + c.c = 4 + + c.a = 2 + c.b = 3 + c.c = 4 + + c.a = 2 + c.b = 3 + c.c = 4 + + + x = c.a + x = c.b + x = c.c + + x = c.a + x = c.b + x = c.c + + x = c.a + x = c.b + x = c.c + + x = c.a + x = c.b + x = c.c + + c.a = 2 + c.b = 3 + c.c = 4 + + c.a = 2 + c.b = 3 + c.c = 4 + + c.a = 2 + c.b = 3 + c.c = 4 + + c.a = 2 + c.b = 3 + c.c = 4 + + + x = c.a + x = c.b + x = c.c + + x = c.a + x = c.b + x = c.c + + x = c.a + x = c.b + x = c.c + + x = c.a + x = c.b + x = c.c + + def calibrate(self): + + class c: + pass + + for i in xrange(self.rounds): + pass + +class SpecialInstanceAttribute(Test): + + version = 0.3 + operations = 5*(12 + 12) + rounds = 100000 + + def test(self): + + class c: + pass + o = c() + + for i in xrange(self.rounds): + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + o.__a__ = 2 + o.__b__ = 3 + o.__c__ = 4 + + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + x = o.__a__ + x = o.__b__ + x = o.__c__ + + def calibrate(self): + + class c: + pass + o = c() + + for i in xrange(self.rounds): + pass + +class NormalInstanceAttribute(Test): + + version = 0.3 + operations = 5*(12 + 12) + rounds = 100000 + + def test(self): + + class c: + pass + o = c() + + for i in xrange(self.rounds): + + o.a = 2 + o.b = 3 + o.c = 4 + + o.a = 2 + o.b = 3 + o.c = 4 + + o.a = 2 + o.b = 3 + o.c = 4 + + o.a = 2 + o.b = 3 + o.c = 4 + + + x = o.a + x = o.b + x = o.c + + x = o.a + x = o.b + x = o.c + + x = o.a + x = o.b + x = o.c + + x = o.a + x = o.b + x = o.c + + o.a = 2 + o.b = 3 + o.c = 4 + + o.a = 2 + o.b = 3 + o.c = 4 + + o.a = 2 + o.b = 3 + o.c = 4 + + o.a = 2 + o.b = 3 + o.c = 4 + + + x = o.a + x = o.b + x = o.c + + x = o.a + x = o.b + x = o.c + + x = o.a + x = o.b + x = o.c + + x = o.a + x = o.b + x = o.c + + o.a = 2 + o.b = 3 + o.c = 4 + + o.a = 2 + o.b = 3 + o.c = 4 + + o.a = 2 + o.b = 3 + o.c = 4 + + o.a = 2 + o.b = 3 + o.c = 4 + + + x = o.a + x = o.b + x = o.c + + x = o.a + x = o.b + x = o.c + + x = o.a + x = o.b + x = o.c + + x = o.a + x = o.b + x = o.c + + o.a = 2 + o.b = 3 + o.c = 4 + + o.a = 2 + o.b = 3 + o.c = 4 + + o.a = 2 + o.b = 3 + o.c = 4 + + o.a = 2 + o.b = 3 + o.c = 4 + + + x = o.a + x = o.b + x = o.c + + x = o.a + x = o.b + x = o.c + + x = o.a + x = o.b + x = o.c + + x = o.a + x = o.b + x = o.c + + o.a = 2 + o.b = 3 + o.c = 4 + + o.a = 2 + o.b = 3 + o.c = 4 + + o.a = 2 + o.b = 3 + o.c = 4 + + o.a = 2 + o.b = 3 + o.c = 4 + + + x = o.a + x = o.b + x = o.c + + x = o.a + x = o.b + x = o.c + + x = o.a + x = o.b + x = o.c + + x = o.a + x = o.b + x = o.c + + def calibrate(self): + + class c: + pass + o = c() + + for i in xrange(self.rounds): + pass + +class BuiltinMethodLookup(Test): + + version = 0.3 + operations = 5*(3*5 + 3*5) + rounds = 70000 + + def test(self): + + l = [] + d = {} + + for i in xrange(self.rounds): + + l.append + l.append + l.append + l.append + l.append + + l.insert + l.insert + l.insert + l.insert + l.insert + + l.sort + l.sort + l.sort + l.sort + l.sort + + d.has_key + d.has_key + d.has_key + d.has_key + d.has_key + + d.items + d.items + d.items + d.items + d.items + + d.get + d.get + d.get + d.get + d.get + + l.append + l.append + l.append + l.append + l.append + + l.insert + l.insert + l.insert + l.insert + l.insert + + l.sort + l.sort + l.sort + l.sort + l.sort + + d.has_key + d.has_key + d.has_key + d.has_key + d.has_key + + d.items + d.items + d.items + d.items + d.items + + d.get + d.get + d.get + d.get + d.get + + l.append + l.append + l.append + l.append + l.append + + l.insert + l.insert + l.insert + l.insert + l.insert + + l.sort + l.sort + l.sort + l.sort + l.sort + + d.has_key + d.has_key + d.has_key + d.has_key + d.has_key + + d.items + d.items + d.items + d.items + d.items + + d.get + d.get + d.get + d.get + d.get + + l.append + l.append + l.append + l.append + l.append + + l.insert + l.insert + l.insert + l.insert + l.insert + + l.sort + l.sort + l.sort + l.sort + l.sort + + d.has_key + d.has_key + d.has_key + d.has_key + d.has_key + + d.items + d.items + d.items + d.items + d.items + + d.get + d.get + d.get + d.get + d.get + + l.append + l.append + l.append + l.append + l.append + + l.insert + l.insert + l.insert + l.insert + l.insert + + l.sort + l.sort + l.sort + l.sort + l.sort + + d.has_key + d.has_key + d.has_key + d.has_key + d.has_key + + d.items + d.items + d.items + d.items + d.items + + d.get + d.get + d.get + d.get + d.get + + def calibrate(self): + + l = [] + d = {} + + for i in xrange(self.rounds): + pass + diff --git a/Tools/pybench/Numbers.py b/Tools/pybench/Numbers.py new file mode 100644 index 0000000..75cf2ed --- /dev/null +++ b/Tools/pybench/Numbers.py @@ -0,0 +1,784 @@ +from pybench import Test + +class CompareIntegers(Test): + + version = 0.1 + operations = 30 * 5 + rounds = 120000 + + def test(self): + + for i in xrange(self.rounds): + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + 2 < 3 + 2 > 3 + 2 == 3 + 2 > 3 + 2 < 3 + + def calibrate(self): + + for i in xrange(self.rounds): + pass + + +class CompareFloats(Test): + + version = 0.1 + operations = 30 * 5 + rounds = 60000 + + def test(self): + + for i in xrange(self.rounds): + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + 2.1 < 3.31 + 2.1 > 3.31 + 2.1 == 3.31 + 2.1 > 3.31 + 2.1 < 3.31 + + def calibrate(self): + + for i in xrange(self.rounds): + pass + + +class CompareFloatsIntegers(Test): + + version = 0.1 + operations = 30 * 5 + rounds = 60000 + + def test(self): + + for i in xrange(self.rounds): + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + 2.1 < 4 + 2.1 > 4 + 2.1 == 4 + 2.1 > 4 + 2.1 < 4 + + def calibrate(self): + + for i in xrange(self.rounds): + pass + + +class CompareLongs(Test): + + version = 0.1 + operations = 30 * 5 + rounds = 60000 + + def test(self): + + for i in xrange(self.rounds): + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + 1234567890L < 3456789012345L + 1234567890L > 3456789012345L + 1234567890L == 3456789012345L + 1234567890L > 3456789012345L + 1234567890L < 3456789012345L + + def calibrate(self): + + for i in xrange(self.rounds): + pass diff --git a/Tools/pybench/README b/Tools/pybench/README new file mode 100644 index 0000000..634e41b --- /dev/null +++ b/Tools/pybench/README @@ -0,0 +1,372 @@ +________________________________________________________________________ + +PYBENCH - A Python Benchmark Suite +________________________________________________________________________ + + Extendable suite of of low-level benchmarks for measuring + the performance of the Python implementation + (interpreter, compiler or VM). + +pybench is a collection of tests that provides a standardized way to +measure the performance of Python implementations. It takes a very +close look at different aspects of Python programs and let's you +decide which factors are more important to you than others, rather +than wrapping everything up in one number, like the other performance +tests do (e.g. pystone which is included in the Python Standard +Library). + +pybench has been used in the past by several Python developers to +track down performance bottlenecks or to demonstrate the impact of +optimizations and new features in Python. + +The command line interface for pybench is the file pybench.py. Run +this script with option '--help' to get a listing of the possible +options. Without options, pybench will simply execute the benchmark +and then print out a report to stdout. + + +Micro-Manual +------------ + +Run 'pybench.py -h' to see the help screen. +Run 'pybench.py' to just let the benchmark suite do it's thing and +'pybench.py -f <file>' to have it store the results in a file too. + +This is the current output of pybench.py --help: + +Synopsis: + pybench.py [option] files... + +Options and default settings: + -n arg number of rounds (10) + -f arg save benchmark to file arg () + -c arg compare benchmark with the one in file arg () + -s arg show benchmark in file arg, then exit () + -S show statistics of benchmarks (0) + -w arg set warp factor to arg (20) + -d hide noise in compares (0) + --no-gc disable garbage collection (0) + -v generate verbose output + -h show this help text + --help show this help text + --debug enable debugging + --copyright show copyright + --examples show examples of usage + +Version: + 1.3 + +The normal operation is to run the suite and display the +results. Use -f to save them for later reuse or comparisms. + +Examples: + +python1.5 pybench.py -w 100 -f p15 +python1.4 pybench.py -w 100 -f p14 +python pybench.py -s p15 -c p14 + + +License +------- + +See LICENSE file. + + +Sample output +------------- + +PYBENCH 1.3 + +Machine Details: + Platform ID: Linux-2.6.8-24.19-default-x86_64-with-SuSE-9.2-x86-64 + Executable: /home/lemburg/projects/Python/Installation/bin/python + Python: 2.5a1.0 + Compiler: GCC 3.3.4 (pre 3.3.5 20040809) + Build: Apr 9 2006 01:50:57 (#trunk) + +Searching for tests... + BuiltinFunctionCalls + BuiltinMethodLookup + CompareFloats + CompareFloatsIntegers + CompareIntegers + CompareInternedStrings + CompareLongs + CompareStrings + CompareUnicode + ConcatStrings + ConcatUnicode + CreateInstances + CreateStringsWithConcat + CreateUnicodeWithConcat + DictCreation + DictWithFloatKeys + DictWithIntegerKeys + DictWithStringKeys + ForLoops + IfThenElse + ListSlicing + NestedForLoops + NormalClassAttribute + NormalInstanceAttribute + PythonFunctionCalls + PythonMethodCalls + Recursion + SecondImport + SecondPackageImport + SecondSubmoduleImport + SimpleComplexArithmetic + SimpleDictManipulation + SimpleFloatArithmetic + SimpleIntFloatArithmetic + SimpleIntegerArithmetic + SimpleListManipulation + SimpleLongArithmetic + SmallLists + SmallTuples + SpecialClassAttribute + SpecialInstanceAttribute + StringMappings + StringPredicates + StringSlicing + TryExcept + TryRaiseExcept + TupleSlicing + UnicodeMappings + UnicodePredicates + UnicodeProperties + UnicodeSlicing + +Running 10 round(s) of the suite: + +... + + Round 10 real abs overhead + BuiltinFunctionCalls: 0.030r 0.030a 0.000o + BuiltinMethodLookup: 0.059r 0.060a 0.001o + CompareFloats: 0.050r 0.050a 0.000o + CompareFloatsIntegers: 0.050r 0.050a 0.000o + CompareIntegers: 0.070r 0.070a 0.000o + CompareInternedStrings: 0.039r 0.040a 0.001o + CompareLongs: 0.050r 0.050a 0.000o + CompareStrings: 0.060r 0.060a 0.000o + CompareUnicode: 0.060r 0.060a 0.000o + ConcatStrings: 0.040r 0.040a 0.000o + ConcatUnicode: 0.050r 0.050a 0.000o + CreateInstances: 0.050r 0.050a 0.000o + CreateStringsWithConcat: 0.029r 0.030a 0.001o + CreateUnicodeWithConcat: 0.060r 0.060a 0.000o + DictCreation: 0.040r 0.040a 0.000o + DictWithFloatKeys: 0.089r 0.090a 0.000o + DictWithIntegerKeys: 0.059r 0.060a 0.001o + DictWithStringKeys: 0.070r 0.070a 0.001o + ForLoops: 0.050r 0.050a 0.000o + IfThenElse: 0.070r 0.070a 0.000o + ListSlicing: 0.030r 0.030a 0.000o + NestedForLoops: 0.030r 0.030a 0.000o + NormalClassAttribute: 0.060r 0.060a 0.000o + NormalInstanceAttribute: 0.060r 0.060a 0.000o + PythonFunctionCalls: 0.060r 0.060a 0.000o + PythonMethodCalls: 0.050r 0.050a 0.000o + Recursion: 0.050r 0.050a 0.000o + SecondImport: 0.030r 0.030a 0.000o + SecondPackageImport: 0.030r 0.030a 0.000o + SecondSubmoduleImport: 0.040r 0.040a 0.000o + SimpleComplexArithmetic: 0.030r 0.030a 0.000o + SimpleDictManipulation: 0.040r 0.040a 0.000o + SimpleFloatArithmetic: 0.050r 0.050a 0.001o + SimpleIntFloatArithmetic: 0.060r 0.060a 0.000o + SimpleIntegerArithmetic: 0.060r 0.060a 0.000o + SimpleListManipulation: 0.030r 0.030a 0.000o + SimpleLongArithmetic: 0.030r 0.030a 0.000o + SmallLists: 0.050r 0.050a 0.000o + SmallTuples: 0.050r 0.050a 0.000o + SpecialClassAttribute: 0.060r 0.060a 0.000o + SpecialInstanceAttribute: 0.079r 0.080a 0.001o + StringMappings: 0.060r 0.060a 0.000o + StringPredicates: 0.049r 0.050a 0.001o + StringSlicing: 0.039r 0.040a 0.000o + TryExcept: 0.079r 0.080a 0.001o + TryRaiseExcept: 0.059r 0.060a 0.001o + TupleSlicing: 0.050r 0.050a 0.000o + UnicodeMappings: 0.070r 0.070a 0.001o + UnicodePredicates: 0.059r 0.060a 0.001o + UnicodeProperties: 0.059r 0.060a 0.001o + UnicodeSlicing: 0.050r 0.050a 0.000o + ---------------------- + Average round time: 2.937 seconds + + +Tests: per run per oper. overhead +------------------------------------------------------------------------ + BuiltinFunctionCalls: 29.85 ms 0.23 us 0.00 ms + BuiltinMethodLookup: 66.85 ms 0.13 us 0.50 ms + CompareFloats: 43.00 ms 0.10 us 0.00 ms + CompareFloatsIntegers: 51.80 ms 0.12 us 0.00 ms + CompareIntegers: 70.70 ms 0.08 us 0.50 ms + CompareInternedStrings: 41.40 ms 0.08 us 0.50 ms + CompareLongs: 47.90 ms 0.11 us 0.00 ms + CompareStrings: 58.50 ms 0.12 us 0.50 ms + CompareUnicode: 56.55 ms 0.15 us 0.50 ms + ConcatStrings: 44.75 ms 0.30 us 0.00 ms + ConcatUnicode: 54.55 ms 0.36 us 0.50 ms + CreateInstances: 50.95 ms 1.21 us 0.00 ms + CreateStringsWithConcat: 28.85 ms 0.14 us 0.50 ms + CreateUnicodeWithConcat: 53.75 ms 0.27 us 0.00 ms + DictCreation: 41.90 ms 0.28 us 0.00 ms + DictWithFloatKeys: 88.50 ms 0.15 us 0.50 ms + DictWithIntegerKeys: 62.55 ms 0.10 us 0.50 ms + DictWithStringKeys: 60.50 ms 0.10 us 0.50 ms + ForLoops: 46.90 ms 4.69 us 0.00 ms + IfThenElse: 60.55 ms 0.09 us 0.00 ms + ListSlicing: 29.90 ms 8.54 us 0.00 ms + NestedForLoops: 33.95 ms 0.10 us 0.00 ms + NormalClassAttribute: 62.75 ms 0.10 us 0.50 ms + NormalInstanceAttribute: 61.80 ms 0.10 us 0.50 ms + PythonFunctionCalls: 60.00 ms 0.36 us 0.00 ms + PythonMethodCalls: 50.00 ms 0.67 us 0.00 ms + Recursion: 46.85 ms 3.75 us 0.00 ms + SecondImport: 35.00 ms 1.40 us 0.00 ms + SecondPackageImport: 32.00 ms 1.28 us 0.00 ms + SecondSubmoduleImport: 38.00 ms 1.52 us 0.00 ms + SimpleComplexArithmetic: 26.85 ms 0.12 us 0.00 ms + SimpleDictManipulation: 40.85 ms 0.14 us 0.00 ms + SimpleFloatArithmetic: 48.70 ms 0.09 us 0.50 ms + SimpleIntFloatArithmetic: 57.70 ms 0.09 us 0.00 ms + SimpleIntegerArithmetic: 58.75 ms 0.09 us 0.50 ms + SimpleListManipulation: 34.80 ms 0.13 us 0.00 ms + SimpleLongArithmetic: 30.95 ms 0.19 us 0.50 ms + SmallLists: 47.60 ms 0.19 us 0.00 ms + SmallTuples: 48.80 ms 0.20 us 0.50 ms + SpecialClassAttribute: 61.70 ms 0.10 us 0.00 ms + SpecialInstanceAttribute: 76.70 ms 0.13 us 0.50 ms + StringMappings: 58.70 ms 0.47 us 0.00 ms + StringPredicates: 50.00 ms 0.18 us 1.00 ms + StringSlicing: 39.65 ms 0.23 us 0.50 ms + TryExcept: 84.45 ms 0.06 us 0.50 ms + TryRaiseExcept: 61.75 ms 4.12 us 0.50 ms + TupleSlicing: 48.95 ms 0.47 us 0.00 ms + UnicodeMappings: 71.50 ms 3.97 us 0.50 ms + UnicodePredicates: 52.75 ms 0.23 us 1.00 ms + UnicodeProperties: 61.90 ms 0.31 us 1.00 ms + UnicodeSlicing: 53.75 ms 0.31 us 0.50 ms +------------------------------------------------------------------------ + Average round time: 2937.00 ms + +________________________________________________________________________ + +Writing New Tests +________________________________________________________________________ + +pybench tests are simple modules defining one or more pybench.Test +subclasses. + +Writing a test essentially boils down to providing two methods: +.test() which runs .rounds number of .operations test operations each +and .calibrate() which does the same except that it doesn't actually +execute the operations. + + +Here's an example: +------------------ + +from pybench import Test + +class IntegerCounting(Test): + + # Version number of the test as float (x.yy); this is important + # for comparisons of benchmark runs - tests with unequal version + # number will not get compared. + version = 1.0 + + # The number of abstract operations done in each round of the + # test. An operation is the basic unit of what you want to + # measure. The benchmark will output the amount of run-time per + # operation. Note that in order to raise the measured timings + # significantly above noise level, it is often required to repeat + # sets of operations more than once per test round. The measured + # overhead per test round should be less than 1 second. + operations = 20 + + # Number of rounds to execute per test run. This should be + # adjusted to a figure that results in a test run-time of between + # 20-50 seconds. + rounds = 100000 + + def test(self): + + """ Run the test. + + The test needs to run self.rounds executing + self.operations number of operations each. + + """ + # Init the test + a = 1 + + # Run test rounds + # + # NOTE: Use xrange() for all test loops unless you want to face + # a 20MB process ! + # + for i in xrange(self.rounds): + + # Repeat the operations per round to raise the run-time + # per operation significantly above the noise level of the + # for-loop overhead. + + # Execute 20 operations (a += 1): + a += 1 + a += 1 + a += 1 + a += 1 + a += 1 + a += 1 + a += 1 + a += 1 + a += 1 + a += 1 + a += 1 + a += 1 + a += 1 + a += 1 + a += 1 + a += 1 + a += 1 + a += 1 + a += 1 + a += 1 + + def calibrate(self): + + """ Calibrate the test. + + This method should execute everything that is needed to + setup and run the test - except for the actual operations + that you intend to measure. pybench uses this method to + measure the test implementation overhead. + + """ + # Init the test + a = 1 + + # Run test rounds (without actually doing any operation) + for i in xrange(self.rounds): + + # Skip the actual execution of the operations, since we + # only want to measure the test's administration overhead. + pass + +Registering a new test module +----------------------------- + +To register a test module with pybench, the classes need to be +imported into the pybench.Setup module. pybench will then scan all the +symbols defined in that module for subclasses of pybench.Test and +automatically add them to the benchmark suite. + + +Have fun, +-- +Marc-Andre Lemburg +mal@lemburg.com diff --git a/Tools/pybench/Setup.py b/Tools/pybench/Setup.py new file mode 100644 index 0000000..906a2a9 --- /dev/null +++ b/Tools/pybench/Setup.py @@ -0,0 +1,35 @@ +#!python + +# Setup file for pybench +# +# This file has to import all tests to be run; it is executed as +# Python source file, so you can do all kinds of manipulations here +# rather than having to edit the tests themselves. +# +# Note: Please keep this module compatible to Python 1.5.2. +# +# Tests may include features in later Python versions, but these +# should then be embedded in try-except clauses in this configuration +# module. + +# Defaults +Number_of_rounds = 10 +Warp_factor = 20 + +# Import tests +from Arithmetic import * +from Calls import * +from Constructs import * +from Lookups import * +from Instances import * +from Lists import * +from Tuples import * +from Dict import * +from Exceptions import * +from Imports import * +from Strings import * +from Numbers import * +try: + from Unicode import * +except (ImportError, SyntaxError): + pass diff --git a/Tools/pybench/Strings.py b/Tools/pybench/Strings.py new file mode 100644 index 0000000..5ab458e --- /dev/null +++ b/Tools/pybench/Strings.py @@ -0,0 +1,564 @@ +from pybench import Test +from string import join + +class ConcatStrings(Test): + + version = 0.1 + operations = 10 * 5 + rounds = 60000 + + def test(self): + + # Make sure the strings are *not* interned + s = join(map(str,range(100))) + t = join(map(str,range(1,101))) + + for i in xrange(self.rounds): + t + s + t + s + t + s + t + s + t + s + + t + s + t + s + t + s + t + s + t + s + + t + s + t + s + t + s + t + s + t + s + + t + s + t + s + t + s + t + s + t + s + + t + s + t + s + t + s + t + s + t + s + + t + s + t + s + t + s + t + s + t + s + + t + s + t + s + t + s + t + s + t + s + + t + s + t + s + t + s + t + s + t + s + + t + s + t + s + t + s + t + s + t + s + + t + s + t + s + t + s + t + s + t + s + + def calibrate(self): + + s = join(map(str,range(100))) + t = join(map(str,range(1,101))) + + for i in xrange(self.rounds): + pass + + +class CompareStrings(Test): + + version = 0.2 + operations = 10 * 5 + rounds = 200000 + + def test(self): + + # Make sure the strings are *not* interned + s = join(map(str,range(10))) + t = join(map(str,range(10))) + "abc" + + for i in xrange(self.rounds): + t < s + t > s + t == s + t > s + t < s + + t < s + t > s + t == s + t > s + t < s + + t < s + t > s + t == s + t > s + t < s + + t < s + t > s + t == s + t > s + t < s + + t < s + t > s + t == s + t > s + t < s + + t < s + t > s + t == s + t > s + t < s + + t < s + t > s + t == s + t > s + t < s + + t < s + t > s + t == s + t > s + t < s + + t < s + t > s + t == s + t > s + t < s + + t < s + t > s + t == s + t > s + t < s + + def calibrate(self): + + s = join(map(str,range(10))) + t = join(map(str,range(10))) + "abc" + + for i in xrange(self.rounds): + pass + + +class CompareInternedStrings(Test): + + version = 0.1 + operations = 10 * 5 + rounds = 200000 + + def test(self): + + # Make sure the strings *are* interned + s = intern(join(map(str,range(10)))) + t = s + + for i in xrange(self.rounds): + t == s + t == s + t >= s + t > s + t < s + + t == s + t == s + t >= s + t > s + t < s + + t == s + t == s + t >= s + t > s + t < s + + t == s + t == s + t >= s + t > s + t < s + + t == s + t == s + t >= s + t > s + t < s + + t == s + t == s + t >= s + t > s + t < s + + t == s + t == s + t >= s + t > s + t < s + + t == s + t == s + t >= s + t > s + t < s + + t == s + t == s + t >= s + t > s + t < s + + t == s + t == s + t >= s + t > s + t < s + + def calibrate(self): + + s = intern(join(map(str,range(10)))) + t = s + + for i in xrange(self.rounds): + pass + + +class CreateStringsWithConcat(Test): + + version = 0.1 + operations = 10 * 5 + rounds = 80000 + + def test(self): + + for i in xrange(self.rounds): + s = 'om' + s = s + 'xbx' + s = s + 'xcx' + s = s + 'xdx' + s = s + 'xex' + + s = s + 'xax' + s = s + 'xbx' + s = s + 'xcx' + s = s + 'xdx' + s = s + 'xex' + + s = s + 'xax' + s = s + 'xbx' + s = s + 'xcx' + s = s + 'xdx' + s = s + 'xex' + + s = s + 'xax' + s = s + 'xbx' + s = s + 'xcx' + s = s + 'xdx' + s = s + 'xex' + + s = s + 'xax' + s = s + 'xbx' + s = s + 'xcx' + s = s + 'xdx' + s = s + 'xex' + + s = s + 'xax' + s = s + 'xbx' + s = s + 'xcx' + s = s + 'xdx' + s = s + 'xex' + + s = s + 'xax' + s = s + 'xbx' + s = s + 'xcx' + s = s + 'xdx' + s = s + 'xex' + + s = s + 'xax' + s = s + 'xbx' + s = s + 'xcx' + s = s + 'xdx' + s = s + 'xex' + + s = s + 'xax' + s = s + 'xbx' + s = s + 'xcx' + s = s + 'xdx' + s = s + 'xex' + + s = s + 'xax' + s = s + 'xbx' + s = s + 'xcx' + s = s + 'xdx' + s = s + 'xex' + + def calibrate(self): + + for i in xrange(self.rounds): + pass + + +class StringSlicing(Test): + + version = 0.1 + operations = 5 * 7 + rounds = 100000 + + def test(self): + + s = join(map(str,range(100))) + + for i in xrange(self.rounds): + + s[50:] + s[:25] + s[50:55] + s[-1:] + s[:1] + s[2:] + s[11:-11] + + s[50:] + s[:25] + s[50:55] + s[-1:] + s[:1] + s[2:] + s[11:-11] + + s[50:] + s[:25] + s[50:55] + s[-1:] + s[:1] + s[2:] + s[11:-11] + + s[50:] + s[:25] + s[50:55] + s[-1:] + s[:1] + s[2:] + s[11:-11] + + s[50:] + s[:25] + s[50:55] + s[-1:] + s[:1] + s[2:] + s[11:-11] + + def calibrate(self): + + s = join(map(str,range(100))) + + for i in xrange(self.rounds): + pass + +### String methods + +if hasattr('', 'lower'): + + class StringMappings(Test): + + version = 0.1 + operations = 3 * (5 + 4 + 2 + 1) + rounds = 70000 + + def test(self): + + s = join(map(chr,range(20)),'') + t = join(map(chr,range(50)),'') + u = join(map(chr,range(100)),'') + v = join(map(chr,range(256)),'') + + for i in xrange(self.rounds): + + s.lower() + s.lower() + s.lower() + s.lower() + s.lower() + + s.upper() + s.upper() + s.upper() + s.upper() + s.upper() + + s.title() + s.title() + s.title() + s.title() + s.title() + + t.lower() + t.lower() + t.lower() + t.lower() + + t.upper() + t.upper() + t.upper() + t.upper() + + t.title() + t.title() + t.title() + t.title() + + u.lower() + u.lower() + + u.upper() + u.upper() + + u.title() + u.title() + + v.lower() + + v.upper() + + v.title() + + def calibrate(self): + + s = join(map(chr,range(20)),'') + t = join(map(chr,range(50)),'') + u = join(map(chr,range(100)),'') + v = join(map(chr,range(256)),'') + + for i in xrange(self.rounds): + pass + + class StringPredicates(Test): + + version = 0.1 + operations = 10 * 7 + rounds = 80000 + + def test(self): + + data = ('abc', '123', ' ', '\xe4\xf6\xfc', '\xdf'*10) + len_data = len(data) + + for i in xrange(self.rounds): + s = data[i % len_data] + + s.isalnum() + s.isalpha() + s.isdigit() + s.islower() + s.isspace() + s.istitle() + s.isupper() + + s.isalnum() + s.isalpha() + s.isdigit() + s.islower() + s.isspace() + s.istitle() + s.isupper() + + s.isalnum() + s.isalpha() + s.isdigit() + s.islower() + s.isspace() + s.istitle() + s.isupper() + + s.isalnum() + s.isalpha() + s.isdigit() + s.islower() + s.isspace() + s.istitle() + s.isupper() + + s.isalnum() + s.isalpha() + s.isdigit() + s.islower() + s.isspace() + s.istitle() + s.isupper() + + s.isalnum() + s.isalpha() + s.isdigit() + s.islower() + s.isspace() + s.istitle() + s.isupper() + + s.isalnum() + s.isalpha() + s.isdigit() + s.islower() + s.isspace() + s.istitle() + s.isupper() + + s.isalnum() + s.isalpha() + s.isdigit() + s.islower() + s.isspace() + s.istitle() + s.isupper() + + s.isalnum() + s.isalpha() + s.isdigit() + s.islower() + s.isspace() + s.istitle() + s.isupper() + + s.isalnum() + s.isalpha() + s.isdigit() + s.islower() + s.isspace() + s.istitle() + s.isupper() + + def calibrate(self): + + data = ('abc', '123', ' ', '\u1234\u2345\u3456', '\uFFFF'*10) + data = ('abc', '123', ' ', '\xe4\xf6\xfc', '\xdf'*10) + len_data = len(data) + + for i in xrange(self.rounds): + s = data[i % len_data] + + diff --git a/Tools/pybench/Tuples.py b/Tools/pybench/Tuples.py new file mode 100644 index 0000000..7854def --- /dev/null +++ b/Tools/pybench/Tuples.py @@ -0,0 +1,365 @@ +from pybench import Test + +class TupleSlicing(Test): + + version = 0.31 + operations = 3 * 25 * 10 * 7 + rounds = 400 + + def test(self): + + r = range(25) + + for i in xrange(self.rounds): + + t = tuple(range(100)) + + for j in r: + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + m = t[50:] + m = t[:25] + m = t[50:55] + m = t[:-1] + m = t[1:] + m = t[-10:] + m = t[:10] + + def calibrate(self): + + r = range(25) + + for i in xrange(self.rounds): + + t = tuple(range(100)) + + for j in r: + + pass + +class SmallTuples(Test): + + version = 0.3 + operations = 5*(1 + 3 + 6 + 2) + rounds = 80000 + + def test(self): + + for i in xrange(self.rounds): + + t = (1,2,3,4,5,6) + + a,b,c,d,e,f = t + a,b,c,d,e,f = t + a,b,c,d,e,f = t + + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + + l = list(t) + t = tuple(l) + + t = (1,2,3,4,5,6) + + a,b,c,d,e,f = t + a,b,c,d,e,f = t + a,b,c,d,e,f = t + + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + + l = list(t) + t = tuple(l) + + t = (1,2,3,4,5,6) + + a,b,c,d,e,f = t + a,b,c,d,e,f = t + a,b,c,d,e,f = t + + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + + l = list(t) + t = tuple(l) + + t = (1,2,3,4,5,6) + + a,b,c,d,e,f = t + a,b,c,d,e,f = t + a,b,c,d,e,f = t + + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + + l = list(t) + t = tuple(l) + + t = (1,2,3,4,5,6) + + a,b,c,d,e,f = t + a,b,c,d,e,f = t + a,b,c,d,e,f = t + + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + a,b,c = t[:3] + + l = list(t) + t = tuple(l) + + def calibrate(self): + + for i in xrange(self.rounds): + pass + diff --git a/Tools/pybench/Unicode.py b/Tools/pybench/Unicode.py new file mode 100644 index 0000000..855fcf2 --- /dev/null +++ b/Tools/pybench/Unicode.py @@ -0,0 +1,542 @@ +try: + unicode +except NameError: + raise ImportError + +from pybench import Test +from string import join + +class ConcatUnicode(Test): + + version = 0.1 + operations = 10 * 5 + rounds = 60000 + + def test(self): + + # Make sure the strings are *not* interned + s = unicode(join(map(str,range(100)))) + t = unicode(join(map(str,range(1,101)))) + + for i in xrange(self.rounds): + t + s + t + s + t + s + t + s + t + s + + t + s + t + s + t + s + t + s + t + s + + t + s + t + s + t + s + t + s + t + s + + t + s + t + s + t + s + t + s + t + s + + t + s + t + s + t + s + t + s + t + s + + t + s + t + s + t + s + t + s + t + s + + t + s + t + s + t + s + t + s + t + s + + t + s + t + s + t + s + t + s + t + s + + t + s + t + s + t + s + t + s + t + s + + t + s + t + s + t + s + t + s + t + s + + def calibrate(self): + + s = unicode(join(map(str,range(100)))) + t = unicode(join(map(str,range(1,101)))) + + for i in xrange(self.rounds): + pass + + +class CompareUnicode(Test): + + version = 0.1 + operations = 10 * 5 + rounds = 150000 + + def test(self): + + # Make sure the strings are *not* interned + s = unicode(join(map(str,range(10)))) + t = unicode(join(map(str,range(10))) + "abc") + + for i in xrange(self.rounds): + t < s + t > s + t == s + t > s + t < s + + t < s + t > s + t == s + t > s + t < s + + t < s + t > s + t == s + t > s + t < s + + t < s + t > s + t == s + t > s + t < s + + t < s + t > s + t == s + t > s + t < s + + t < s + t > s + t == s + t > s + t < s + + t < s + t > s + t == s + t > s + t < s + + t < s + t > s + t == s + t > s + t < s + + t < s + t > s + t == s + t > s + t < s + + t < s + t > s + t == s + t > s + t < s + + def calibrate(self): + + s = unicode(join(map(str,range(10)))) + t = unicode(join(map(str,range(10))) + "abc") + + for i in xrange(self.rounds): + pass + + +class CreateUnicodeWithConcat(Test): + + version = 0.1 + operations = 10 * 5 + rounds = 80000 + + def test(self): + + for i in xrange(self.rounds): + s = u'om' + s = s + u'xbx' + s = s + u'xcx' + s = s + u'xdx' + s = s + u'xex' + + s = s + u'xax' + s = s + u'xbx' + s = s + u'xcx' + s = s + u'xdx' + s = s + u'xex' + + s = s + u'xax' + s = s + u'xbx' + s = s + u'xcx' + s = s + u'xdx' + s = s + u'xex' + + s = s + u'xax' + s = s + u'xbx' + s = s + u'xcx' + s = s + u'xdx' + s = s + u'xex' + + s = s + u'xax' + s = s + u'xbx' + s = s + u'xcx' + s = s + u'xdx' + s = s + u'xex' + + s = s + u'xax' + s = s + u'xbx' + s = s + u'xcx' + s = s + u'xdx' + s = s + u'xex' + + s = s + u'xax' + s = s + u'xbx' + s = s + u'xcx' + s = s + u'xdx' + s = s + u'xex' + + s = s + u'xax' + s = s + u'xbx' + s = s + u'xcx' + s = s + u'xdx' + s = s + u'xex' + + s = s + u'xax' + s = s + u'xbx' + s = s + u'xcx' + s = s + u'xdx' + s = s + u'xex' + + s = s + u'xax' + s = s + u'xbx' + s = s + u'xcx' + s = s + u'xdx' + s = s + u'xex' + + def calibrate(self): + + for i in xrange(self.rounds): + pass + + +class UnicodeSlicing(Test): + + version = 0.1 + operations = 5 * 7 + rounds = 100000 + + def test(self): + + s = unicode(join(map(str,range(100)))) + + for i in xrange(self.rounds): + + s[50:] + s[:25] + s[50:55] + s[-1:] + s[:1] + s[2:] + s[11:-11] + + s[50:] + s[:25] + s[50:55] + s[-1:] + s[:1] + s[2:] + s[11:-11] + + s[50:] + s[:25] + s[50:55] + s[-1:] + s[:1] + s[2:] + s[11:-11] + + s[50:] + s[:25] + s[50:55] + s[-1:] + s[:1] + s[2:] + s[11:-11] + + s[50:] + s[:25] + s[50:55] + s[-1:] + s[:1] + s[2:] + s[11:-11] + + def calibrate(self): + + s = unicode(join(map(str,range(100)))) + + for i in xrange(self.rounds): + pass + +### String methods + +class UnicodeMappings(Test): + + version = 0.1 + operations = 3 * (5 + 4 + 2 + 1) + rounds = 10000 + + def test(self): + + s = join(map(unichr,range(20)),'') + t = join(map(unichr,range(100)),'') + u = join(map(unichr,range(500)),'') + v = join(map(unichr,range(1000)),'') + + for i in xrange(self.rounds): + + s.lower() + s.lower() + s.lower() + s.lower() + s.lower() + + s.upper() + s.upper() + s.upper() + s.upper() + s.upper() + + s.title() + s.title() + s.title() + s.title() + s.title() + + t.lower() + t.lower() + t.lower() + t.lower() + + t.upper() + t.upper() + t.upper() + t.upper() + + t.title() + t.title() + t.title() + t.title() + + u.lower() + u.lower() + + u.upper() + u.upper() + + u.title() + u.title() + + v.lower() + + v.upper() + + v.title() + + def calibrate(self): + + s = join(map(unichr,range(20)),'') + t = join(map(unichr,range(100)),'') + u = join(map(unichr,range(500)),'') + v = join(map(unichr,range(1000)),'') + + for i in xrange(self.rounds): + pass + +class UnicodePredicates(Test): + + version = 0.1 + operations = 5 * 9 + rounds = 100000 + + def test(self): + + data = (u'abc', u'123', u' ', u'\u1234\u2345\u3456', u'\uFFFF'*10) + len_data = len(data) + + for i in xrange(self.rounds): + s = data[i % len_data] + + s.isalnum() + s.isalpha() + s.isdecimal() + s.isdigit() + s.islower() + s.isnumeric() + s.isspace() + s.istitle() + s.isupper() + + s.isalnum() + s.isalpha() + s.isdecimal() + s.isdigit() + s.islower() + s.isnumeric() + s.isspace() + s.istitle() + s.isupper() + + s.isalnum() + s.isalpha() + s.isdecimal() + s.isdigit() + s.islower() + s.isnumeric() + s.isspace() + s.istitle() + s.isupper() + + s.isalnum() + s.isalpha() + s.isdecimal() + s.isdigit() + s.islower() + s.isnumeric() + s.isspace() + s.istitle() + s.isupper() + + s.isalnum() + s.isalpha() + s.isdecimal() + s.isdigit() + s.islower() + s.isnumeric() + s.isspace() + s.istitle() + s.isupper() + + def calibrate(self): + + data = (u'abc', u'123', u' ', u'\u1234\u2345\u3456', u'\uFFFF'*10) + len_data = len(data) + + for i in xrange(self.rounds): + s = data[i % len_data] + +try: + import unicodedata +except ImportError: + pass +else: + class UnicodeProperties(Test): + + version = 0.1 + operations = 5 * 8 + rounds = 100000 + + def test(self): + + data = (u'a', u'1', u' ', u'\u1234', u'\uFFFF') + len_data = len(data) + digit = unicodedata.digit + numeric = unicodedata.numeric + decimal = unicodedata.decimal + category = unicodedata.category + bidirectional = unicodedata.bidirectional + decomposition = unicodedata.decomposition + mirrored = unicodedata.mirrored + combining = unicodedata.combining + + for i in xrange(self.rounds): + + c = data[i % len_data] + + digit(c, None) + numeric(c, None) + decimal(c, None) + category(c) + bidirectional(c) + decomposition(c) + mirrored(c) + combining(c) + + digit(c, None) + numeric(c, None) + decimal(c, None) + category(c) + bidirectional(c) + decomposition(c) + mirrored(c) + combining(c) + + digit(c, None) + numeric(c, None) + decimal(c, None) + category(c) + bidirectional(c) + decomposition(c) + mirrored(c) + combining(c) + + digit(c, None) + numeric(c, None) + decimal(c, None) + category(c) + bidirectional(c) + decomposition(c) + mirrored(c) + combining(c) + + digit(c, None) + numeric(c, None) + decimal(c, None) + category(c) + bidirectional(c) + decomposition(c) + mirrored(c) + combining(c) + + def calibrate(self): + + data = (u'a', u'1', u' ', u'\u1234', u'\uFFFF') + len_data = len(data) + digit = unicodedata.digit + numeric = unicodedata.numeric + decimal = unicodedata.decimal + category = unicodedata.category + bidirectional = unicodedata.bidirectional + decomposition = unicodedata.decomposition + mirrored = unicodedata.mirrored + combining = unicodedata.combining + + for i in xrange(self.rounds): + + c = data[i % len_data] diff --git a/Tools/pybench/package/__init__.py b/Tools/pybench/package/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tools/pybench/package/__init__.py diff --git a/Tools/pybench/package/submodule.py b/Tools/pybench/package/submodule.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tools/pybench/package/submodule.py diff --git a/Tools/pybench/pybench.py b/Tools/pybench/pybench.py new file mode 100755 index 0000000..6f10bd1 --- /dev/null +++ b/Tools/pybench/pybench.py @@ -0,0 +1,461 @@ +#!/usr/local/bin/python -O + +""" A Python Benchmark Suite + +""" +# +# Note: Please keep this module compatible to Python 1.5.2. +# +# Tests may include features in later Python versions, but these +# should then be embedded in try-except clauses in the configuration +# module Setup.py. +# + +# pybench Copyright +__copyright__ = """\ +Copyright (c), 1997-2006, Marc-Andre Lemburg (mal@lemburg.com) +Copyright (c), 2000-2006, eGenix.com Software GmbH (info@egenix.com) + + All Rights Reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee or royalty is hereby +granted, provided that the above copyright notice appear in all copies +and that both that copyright notice and this permission notice appear +in supporting documentation or portions thereof, including +modifications, that you make. + +THE AUTHOR MARC-ANDRE LEMBURG DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, +INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING +FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE ! +""" + +# Version number +__version__ = '1.3' + +# +# NOTE: Use xrange for all test loops unless you want to face +# a 20MB process ! +# +# All tests should have rounds set to values so that a run() +# takes between 20-50 seconds. This is to get fairly good +# clock() values. You can use option -w to speedup the tests +# by a fixed integer factor (the "warp factor"). +# + +import sys,time,operator +from CommandLine import * + +try: + import cPickle + pickle = cPickle +except ImportError: + import pickle + +### Test baseclass + +class Test: + + """ All test must have this class as baseclass. It provides + the necessary interface to the benchmark machinery. + + The tests must set .rounds to a value high enough to let the + test run between 20-50 seconds. This is needed because + clock()-timing only gives rather inaccurate values (on Linux, + for example, it is accurate to a few hundreths of a + second). If you don't want to wait that long, use a warp + factor larger than 1. + + It is also important to set the .operations variable to a + value representing the number of "virtual operations" done per + call of .run(). + + If you change a test in some way, don't forget to increase + it's version number. + + """ + + ### Instance variables that each test should override + + # Version number of the test as float (x.yy); this is important + # for comparisons of benchmark runs - tests with unequal version + # number will not get compared. + version = 1.0 + + # The number of abstract operations done in each round of the + # test. An operation is the basic unit of what you want to + # measure. The benchmark will output the amount of run-time per + # operation. Note that in order to raise the measured timings + # significantly above noise level, it is often required to repeat + # sets of operations more than once per test round. The measured + # overhead per test round should be less than 1 second. + operations = 1 + + # Number of rounds to execute per test run. This should be + # adjusted to a figure that results in a test run-time of between + # 20-50 seconds. + rounds = 100000 + + ### Internal variables + + # Mark this class as implementing a test + is_a_test = 1 + + # Misc. internal variables + last_timing = (0,0,0) # last timing (real,run,calibration) + warp = 1 # warp factor this test uses + cruns = 20 # number of calibration runs + overhead = None # list of calibration timings + + def __init__(self,warp=1): + + if warp > 1: + self.rounds = self.rounds / warp + self.warp = warp + self.times = [] + self.overhead = [] + # We want these to be in the instance dict, so that pickle + # saves them + self.version = self.version + self.operations = self.operations + self.rounds = self.rounds + + def run(self): + + """ Run the test in two phases: first calibrate, then + do the actual test. Be careful to keep the calibration + timing low w/r to the test timing. + + """ + test = self.test + calibrate = self.calibrate + clock = time.clock + cruns = self.cruns + # first calibrate + offset = 0.0 + for i in range(cruns): + t = clock() + calibrate() + t = clock() - t + offset = offset + t + offset = offset / cruns + # now the real thing + t = clock() + test() + t = clock() - t + self.last_timing = (t-offset,t,offset) + self.times.append(t-offset) + + def calibrate(self): + + """ Calibrate the test. + + This method should execute everything that is needed to + setup and run the test - except for the actual operations + that you intend to measure. pybench uses this method to + measure the test implementation overhead. + + """ + return + + def test(self): + + """ Run the test. + + The test needs to run self.rounds executing + self.operations number of operations each. + + """ + # do some tests + return + + def stat(self): + + """ Returns two value: average time per run and average per + operation. + + """ + runs = len(self.times) + if runs == 0: + return 0,0 + totaltime = reduce(operator.add,self.times,0.0) + avg = totaltime / float(runs) + op_avg = totaltime / float(runs * self.rounds * self.operations) + if self.overhead: + totaloverhead = reduce(operator.add,self.overhead,0.0) + ov_avg = totaloverhead / float(runs) + else: + # use self.last_timing - not too accurate + ov_avg = self.last_timing[2] + return avg,op_avg,ov_avg + +### Load Setup + +# This has to be done after the definition of the Test class, since +# the Setup module will import subclasses using this class. + +import Setup + +### Benchmark base class + +class Benchmark: + + name = '?' # Name of the benchmark + rounds = 1 # Number of rounds to run + warp = 1 # Warp factor + roundtime = 0 # Average round time + version = None # Benchmark version number (see __init__) + # as float x.yy + starttime = None # Benchmark start time + + def __init__(self): + + self.tests = {} + self.version = 0.31 + + def load_tests(self,setupmod,warp=1): + + self.warp = warp + tests = self.tests + print 'Searching for tests...' + setupmod.__dict__.values() + for c in setupmod.__dict__.values(): + if hasattr(c,'is_a_test') and c.__name__ != 'Test': + tests[c.__name__] = c(warp) + l = tests.keys() + l.sort() + for t in l: + print ' ',t + print + + def run(self): + + tests = self.tests.items() + tests.sort() + clock = time.clock + print 'Running %i round(s) of the suite: ' % self.rounds + print + self.starttime = time.time() + roundtime = clock() + for i in range(self.rounds): + print ' Round %-25i real abs overhead' % (i+1) + for j in range(len(tests)): + name,t = tests[j] + print '%30s:' % name, + t.run() + print ' %.3fr %.3fa %.3fo' % t.last_timing + print ' ----------------------' + print ' Average round time: %.3f seconds' % \ + ((clock() - roundtime)/(i+1)) + print + self.roundtime = (clock() - roundtime) / self.rounds + print + + def print_stat(self, compare_to=None, hidenoise=0): + + if not compare_to: + print '%-30s per run per oper. overhead' % 'Tests:' + print '-'*72 + tests = self.tests.items() + tests.sort() + for name,t in tests: + avg,op_avg,ov_avg = t.stat() + print '%30s: %10.2f ms %7.2f us %7.2f ms' % \ + (name,avg*1000.0,op_avg*1000000.0,ov_avg*1000.0) + print '-'*72 + print '%30s: %10.2f ms' % \ + ('Average round time',self.roundtime * 1000.0) + + else: + print '%-30s per run per oper. diff *)' % \ + 'Tests:' + print '-'*72 + tests = self.tests.items() + tests.sort() + compatible = 1 + for name,t in tests: + avg,op_avg,ov_avg = t.stat() + try: + other = compare_to.tests[name] + except KeyError: + other = None + if other and other.version == t.version and \ + other.operations == t.operations: + avg1,op_avg1,ov_avg1 = other.stat() + qop_avg = (op_avg/op_avg1-1.0)*100.0 + if hidenoise and abs(qop_avg) < 10: + qop_avg = '' + else: + qop_avg = '%+7.2f%%' % qop_avg + else: + qavg,qop_avg = 'n/a', 'n/a' + compatible = 0 + print '%30s: %10.2f ms %7.2f us %8s' % \ + (name,avg*1000.0,op_avg*1000000.0,qop_avg) + print '-'*72 + if compatible and compare_to.roundtime > 0 and \ + compare_to.version == self.version: + print '%30s: %10.2f ms %+7.2f%%' % \ + ('Average round time',self.roundtime * 1000.0, + ((self.roundtime*self.warp)/ + (compare_to.roundtime*compare_to.warp)-1.0)*100.0) + else: + print '%30s: %10.2f ms n/a' % \ + ('Average round time',self.roundtime * 1000.0) + print + print '*) measured against: %s (rounds=%i, warp=%i)' % \ + (compare_to.name,compare_to.rounds,compare_to.warp) + print + +def print_machine(): + + import platform + print 'Machine Details:' + print ' Platform ID: %s' % platform.platform() + print ' Executable: %s' % sys.executable + # There's a bug in Python 2.2b1+... + if sys.version[:6] == '2.2b1+': + return + print ' Python: %s' % platform.python_version() + print ' Compiler: %s' % platform.python_compiler() + buildno, builddate = platform.python_build() + print ' Build: %s (#%s)' % (builddate, buildno) + +class PyBenchCmdline(Application): + + header = ("PYBENCH - a benchmark test suite for Python " + "interpreters/compilers.") + + version = __version__ + + options = [ArgumentOption('-n','number of rounds',Setup.Number_of_rounds), + ArgumentOption('-f','save benchmark to file arg',''), + ArgumentOption('-c','compare benchmark with the one in file arg',''), + ArgumentOption('-s','show benchmark in file arg, then exit',''), + SwitchOption('-S','show statistics of benchmarks',0), + ArgumentOption('-w','set warp factor to arg',Setup.Warp_factor), + SwitchOption('-d','hide noise in compares', 0), + SwitchOption('--no-gc','disable garbage collection', 0), + ] + + about = """\ +The normal operation is to run the suite and display the +results. Use -f to save them for later reuse or comparisms. + +Examples: + +python1.5 pybench.py -w 100 -f p15 +python1.4 pybench.py -w 100 -f p14 +python pybench.py -s p15 -c p14 +""" + copyright = __copyright__ + + def handle_S(self, value): + + """ Display one line stats for each benchmark file given on the + command line. + + """ + for benchmark in self.files: + try: + f = open(benchmark, 'rb') + bench = pickle.load(f) + f.close() + except IOError: + print '* Error opening/reading file %s' % repr(benchmark) + else: + print '%s,%-.2f,ms' % (benchmark, bench.roundtime*1000.0) + return 0 + + def main(self): + + rounds = self.values['-n'] + reportfile = self.values['-f'] + show_bench = self.values['-s'] + compare_to = self.values['-c'] + hidenoise = self.values['-d'] + warp = self.values['-w'] + nogc = self.values['--no-gc'] + + # Switch off GC + if nogc: + try: + import gc + except ImportError: + nogc = 0 + else: + if self.values['--no-gc']: + gc.disable() + + print 'PYBENCH',__version__ + print + + if not compare_to: + print_machine() + print + + if compare_to: + try: + f = open(compare_to,'rb') + bench = pickle.load(f) + bench.name = compare_to + f.close() + compare_to = bench + except IOError: + print '* Error opening/reading file',compare_to + compare_to = None + + if show_bench: + try: + f = open(show_bench,'rb') + bench = pickle.load(f) + bench.name = show_bench + f.close() + print 'Benchmark: %s (rounds=%i, warp=%i)' % \ + (bench.name,bench.rounds,bench.warp) + print + bench.print_stat(compare_to, hidenoise) + except IOError: + print '* Error opening/reading file',show_bench + print + return + + if reportfile: + if nogc: + print 'Benchmark: %s (rounds=%i, warp=%i, no GC)' % \ + (reportfile,rounds,warp) + else: + print 'Benchmark: %s (rounds=%i, warp=%i)' % \ + (reportfile,rounds,warp) + print + + # Create benchmark object + bench = Benchmark() + bench.rounds = rounds + bench.load_tests(Setup,warp) + try: + bench.run() + except KeyboardInterrupt: + print + print '*** KeyboardInterrupt -- Aborting' + print + return + bench.print_stat(compare_to) + # ring bell + sys.stderr.write('\007') + + if reportfile: + try: + f = open(reportfile,'wb') + bench.name = reportfile + pickle.dump(bench,f) + f.close() + except IOError: + print '* Error opening/writing reportfile' + +if __name__ == '__main__': + PyBenchCmdline() diff --git a/Tools/scripts/byext.py b/Tools/scripts/byext.py index 93759bc..09610b0 100644 --- a/Tools/scripts/byext.py +++ b/Tools/scripts/byext.py @@ -17,7 +17,7 @@ class Stats: elif os.path.isfile(arg): self.statfile(arg) else: - sys.stderr.write("Can't find %s\n" % file) + sys.stderr.write("Can't find %s\n" % arg) self.addstats("<???>", "unknown", 1) def statdir(self, dir): @@ -25,8 +25,8 @@ class Stats: try: names = os.listdir(dir) except os.error, err: - sys.stderr.write("Can't list %s: %s\n" % (file, err)) - self.addstats(ext, "unlistable", 1) + sys.stderr.write("Can't list %s: %s\n" % (dir, err)) + self.addstats("<dir>", "unlistable", 1) return names.sort() for name in names: @@ -42,9 +42,9 @@ class Stats: else: self.statfile(full) - def statfile(self, file): - head, ext = os.path.splitext(file) - head, base = os.path.split(file) + def statfile(self, filename): + head, ext = os.path.splitext(filename) + head, base = os.path.split(filename) if ext == base: ext = "" # E.g. .cvsignore is deemed not to have an extension ext = os.path.normcase(ext) @@ -52,9 +52,9 @@ class Stats: ext = "<none>" self.addstats(ext, "files", 1) try: - f = open(file, "rb") + f = open(filename, "rb") except IOError, err: - sys.stderr.write("Can't open %s: %s\n" % (file, err)) + sys.stderr.write("Can't open %s: %s\n" % (filename, err)) self.addstats(ext, "unopenable", 1) return data = f.read() diff --git a/Tools/scripts/classfix.py b/Tools/scripts/classfix.py index cdf006a..d30700f 100755 --- a/Tools/scripts/classfix.py +++ b/Tools/scripts/classfix.py @@ -30,7 +30,7 @@ # into a program for a different change to Python programs... import sys -import regex +import re import os from stat import * @@ -53,7 +53,7 @@ def main(): if fix(arg): bad = 1 sys.exit(bad) -ispythonprog = regex.compile('^[a-zA-Z0-9_]+\.py$') +ispythonprog = re.compile('^[a-zA-Z0-9_]+\.py$') def ispython(name): return ispythonprog.match(name) >= 0 @@ -148,12 +148,12 @@ def fix(filename): # This expression doesn't catch *all* class definition headers, # but it's pretty darn close. -classexpr = '^\([ \t]*class +[a-zA-Z0-9_]+\) *( *) *\(\(=.*\)?\):' -classprog = regex.compile(classexpr) +classexpr = '^([ \t]*class +[a-zA-Z0-9_]+) *( *) *((=.*)?):' +classprog = re.compile(classexpr) # Expressions for finding base class expressions. -baseexpr = '^ *\(.*\) *( *) *$' -baseprog = regex.compile(baseexpr) +baseexpr = '^ *(.*) *( *) *$' +baseprog = re.compile(baseexpr) def fixline(line): if classprog.match(line) < 0: # No 'class' keyword -- no change diff --git a/Tools/scripts/fixcid.py b/Tools/scripts/fixcid.py index 42aa835..433a425 100755 --- a/Tools/scripts/fixcid.py +++ b/Tools/scripts/fixcid.py @@ -35,7 +35,7 @@ # files. import sys -import regex +import re import os from stat import * import getopt @@ -90,7 +90,7 @@ def main(): # Change this regular expression to select a different set of files Wanted = '^[a-zA-Z0-9_]+\.[ch]$' def wanted(name): - return regex.match(Wanted, name) >= 0 + return re.match(Wanted, name) >= 0 def recursedown(dirname): dbg('recursedown(%r)\n' % (dirname,)) @@ -212,12 +212,12 @@ Number = Floatnumber + '\|' + Intnumber # Anything else is an operator -- don't list this explicitly because of '/*' OutsideComment = (Identifier, Number, String, Char, CommentStart) -OutsideCommentPattern = '\(' + '\|'.join(OutsideComment) + '\)' -OutsideCommentProgram = regex.compile(OutsideCommentPattern) +OutsideCommentPattern = '(' + '|'.join(OutsideComment) + ')' +OutsideCommentProgram = re.compile(OutsideCommentPattern) InsideComment = (Identifier, Number, CommentEnd) -InsideCommentPattern = '\(' + '\|'.join(InsideComment) + '\)' -InsideCommentProgram = regex.compile(InsideCommentPattern) +InsideCommentPattern = '(' + '|'.join(InsideComment) + ')' +InsideCommentProgram = re.compile(InsideCommentPattern) def initfixline(): global Program diff --git a/Tools/scripts/ifdef.py b/Tools/scripts/ifdef.py index 7e7b5cc..2ed7a66 100755 --- a/Tools/scripts/ifdef.py +++ b/Tools/scripts/ifdef.py @@ -27,7 +27,6 @@ # preprocessor commands. import sys -import regex import getopt defs = [] diff --git a/Tools/scripts/methfix.py b/Tools/scripts/methfix.py index a872ab7..b81871f 100755 --- a/Tools/scripts/methfix.py +++ b/Tools/scripts/methfix.py @@ -27,7 +27,7 @@ # into a program for a different change to Python programs... import sys -import regex +import re import os from stat import * @@ -50,7 +50,7 @@ def main(): if fix(arg): bad = 1 sys.exit(bad) -ispythonprog = regex.compile('^[a-zA-Z0-9_]+\.py$') +ispythonprog = re.compile('^[a-zA-Z0-9_]+\.py$') def ispython(name): return ispythonprog.match(name) >= 0 @@ -101,7 +101,7 @@ def fix(filename): if lineno == 1 and g is None and line[:2] == '#!': # Check for non-Python scripts words = line[2:].split() - if words and regex.search('[pP]ython', words[0]) < 0: + if words and re.search('[pP]ython', words[0]) < 0: msg = filename + ': ' + words[0] msg = msg + ' script; not fixed\n' err(msg) @@ -158,8 +158,8 @@ def fix(filename): return 0 -fixpat = '^[ \t]+def +[a-zA-Z0-9_]+ *( *self *, *\(( *\(.*\) *)\) *) *:' -fixprog = regex.compile(fixpat) +fixpat = '^[ \t]+def +[a-zA-Z0-9_]+ *( *self *, *(( *(.*) *)) *) *:' +fixprog = re.compile(fixpat) def fixline(line): if fixprog.match(line) >= 0: diff --git a/Tools/scripts/objgraph.py b/Tools/scripts/objgraph.py index 01060f9..f74c2b6 100755 --- a/Tools/scripts/objgraph.py +++ b/Tools/scripts/objgraph.py @@ -22,7 +22,7 @@ import sys import os import getopt -import regex +import re # Types of symbols. # @@ -32,7 +32,7 @@ ignore = 'Nntrgdsbavuc' # Regular expression to parse "nm -o" output. # -matcher = regex.compile('\(.*\):\t?........ \(.\) \(.*\)$') +matcher = re.compile('(.*):\t?........ (.) (.*)$') # Store "item" in "dict" under "key". # The dictionary maps keys to lists of items. diff --git a/Tools/scripts/pathfix.py b/Tools/scripts/pathfix.py index 5cb5add..7f6f191 100755 --- a/Tools/scripts/pathfix.py +++ b/Tools/scripts/pathfix.py @@ -20,7 +20,7 @@ # into a program for a different change to Python programs... import sys -import regex +import re import os from stat import * import getopt @@ -59,7 +59,7 @@ def main(): if fix(arg): bad = 1 sys.exit(bad) -ispythonprog = regex.compile('^[a-zA-Z0-9_]+\.py$') +ispythonprog = re.compile('^[a-zA-Z0-9_]+\.py$') def ispython(name): return ispythonprog.match(name) >= 0 diff --git a/Tools/scripts/pdeps.py b/Tools/scripts/pdeps.py index e835f84..da63e35 100755 --- a/Tools/scripts/pdeps.py +++ b/Tools/scripts/pdeps.py @@ -21,7 +21,7 @@ import sys -import regex +import re import os @@ -57,8 +57,8 @@ def main(): # Compiled regular expressions to search for import statements # -m_import = regex.compile('^[ \t]*from[ \t]+\([^ \t]+\)[ \t]+') -m_from = regex.compile('^[ \t]*import[ \t]+\([^#]+\)') +m_import = re.compile('^[ \t]*from[ \t]+([^ \t]+)[ \t]+') +m_from = re.compile('^[ \t]*import[ \t]+([^#]+)') # Collect data from one file diff --git a/Tools/unicode/Makefile b/Tools/unicode/Makefile index f266d4d..fbd3557 100644 --- a/Tools/unicode/Makefile +++ b/Tools/unicode/Makefile @@ -15,7 +15,7 @@ RM = /bin/rm all: distclean mappings codecs -codecs: misc windows iso apple ebcdic custom-mappings +codecs: misc windows iso apple ebcdic custom-mappings cjk ### Mappings @@ -72,6 +72,9 @@ ebcdic: build/ $(PYTHON) gencodec.py MAPPINGS/VENDORS/MICSFT/EBCDIC/ build/ $(RM) -f build/readme.* +cjk: build/ + $(PYTHON) gencjkcodecs.py build/ + ### Cleanup clean: diff --git a/Tools/unicode/gencjkcodecs.py b/Tools/unicode/gencjkcodecs.py new file mode 100644 index 0000000..975c19c --- /dev/null +++ b/Tools/unicode/gencjkcodecs.py @@ -0,0 +1,68 @@ +import os, string + +codecs = { + 'cn': ('gb2312', 'gbk', 'gb18030', 'hz'), + 'tw': ('big5', 'cp950'), + 'hk': ('big5hkscs',), + 'jp': ('cp932', 'shift_jis', 'euc_jp', 'euc_jisx0213', 'shift_jisx0213', + 'euc_jis_2004', 'shift_jis_2004'), + 'kr': ('cp949', 'euc_kr', 'johab'), + 'iso2022': ('iso2022_jp', 'iso2022_jp_1', 'iso2022_jp_2', + 'iso2022_jp_2004', 'iso2022_jp_3', 'iso2022_jp_ext', + 'iso2022_kr'), +} + +TEMPLATE = string.Template("""\ +# +# $encoding.py: Python Unicode Codec for $ENCODING +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_$owner, codecs +import _multibytecodec as mbc + +codec = _codecs_$owner.getcodec('$encoding') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='$encoding', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) +""") + +def gencodecs(prefix): + for loc, encodings in codecs.iteritems(): + for enc in encodings: + code = TEMPLATE.substitute(ENCODING=enc.upper(), + encoding=enc.lower(), + owner=loc) + codecpath = os.path.join(prefix, enc + '.py') + open(codecpath, 'w').write(code) + +if __name__ == '__main__': + import sys + gencodecs(sys.argv[1]) diff --git a/Tools/unicode/gencodec.py b/Tools/unicode/gencodec.py index bb1c9da..3cfef20 100644 --- a/Tools/unicode/gencodec.py +++ b/Tools/unicode/gencodec.py @@ -348,7 +348,7 @@ def getregentry(): l.extend(encoding_map_code) # Final new-line - l.append('\n') + l.append('') return '\n'.join(l).expandtabs() |