PageRenderTime 61ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/pypy/translator/goal/bench-windows.py

https://bitbucket.org/onyxfish/pypy
Python | 186 lines | 177 code | 2 blank | 7 comment | 0 complexity | e5be6e935b2aec58562c0a7ecba38eb8 MD5 | raw file
  1. # benchmarks on a windows machine.
  2. # to be executed in the goal folder,
  3. # where a couple of .exe files is expected.
  4. USE_HIGH_PRIORITY = True
  5. # usage with high priority:
  6. # the program will try to import subprocess.
  7. # you can have this with python older than 2.4: copy
  8. # subprocess into lib and change line 392 to use win32
  9. current_result = """
  10. executable richards pystone size (MB)
  11. pypy-c-17439 37413 47.7x 678.4 60.7x 5.65
  12. pypy-c-17600-lo 26352 33.6x 906.2 45.4x 6.43
  13. pypy-c-17634-lo 20108 25.7x 1023.5 40.2x 6.42
  14. pypy-c-17649-lo 22612 28.9x 1042.0 39.5x 6.41
  15. pypy-c-17674-lo 19248 24.6x 1358.8 30.3x 6.40
  16. pypy-c-17674 12402 15.8x 1941.4 21.2x 7.37
  17. pypy-c-17439-lo 29638 37.8x 971.4 42.4x 6.49
  18. pypy-c-17707 14095 18.0x 2092.7 19.7x 7.37
  19. pypy-c-17707-lo 19102 24.4x 1354.7 30.4x 6.40
  20. pypy-c-17707-lo-range 18786 24.0x 2800.8 14.7x 6.40
  21. pypy-c-17707-range 13980 17.8x 2899.9 14.2x 7.38
  22. pypy-c-17743 13944 17.8x 2800.3 14.7x 7.30
  23. pypy-c-17761-samuele 13243 16.9x 2983.3 13.8x 7.69
  24. pypy-c-17794-ref-crash 41088 52.4x 1084.5 37.9x 14.62
  25. pypy-c-17950 12888 16.4x 3203.0 12.8x 5.49
  26. pypy-c-18236 9263 11.8x 3702.8 11.1x 5.12
  27. python 2.4.1 783 1.0x 41150.3 1.0x 0.96
  28. Defaults are: --gc=boehm
  29. 'lo' indicates --lowmem
  30. STarting with rev. 18236, gc_pypy.dll is used
  31. """
  32. import os, sys, pickle, md5
  33. try:
  34. from subprocess import *
  35. except ImportError:
  36. Popen = None
  37. PYSTONE_CMD = 'from test import pystone;pystone.main(%s)'
  38. PYSTONE_PATTERN = 'This machine benchmarks at'
  39. RICHARDS_CMD = 'from richards import *;main(iterations=%d)'
  40. RICHARDS_PATTERN = 'Average time per iteration:'
  41. def get_result(txt, pattern):
  42. for line in txt.split('\n'):
  43. if line.startswith(pattern):
  44. break
  45. else:
  46. raise ValueError, 'this is no valid output: %r' % txt
  47. return float(line.split()[len(pattern.split())])
  48. def run_cmd(cmd):
  49. print "running", cmd
  50. pipe = os.popen(cmd + ' 2>&1')
  51. result = pipe.read()
  52. print "done"
  53. return result
  54. def run_cmd_subprocess(cmd):
  55. print "running", cmd
  56. result = Popen(cmd, stdout=PIPE, creationflags=CREATIONFLAGS
  57. ).communicate()[0]
  58. print "done"
  59. return result
  60. CREATIONFLAGS = 0
  61. if Popen:
  62. run_cmd = run_cmd_subprocess
  63. try:
  64. import win32con, win32api
  65. except ImportError:
  66. pass
  67. else:
  68. if USE_HIGH_PRIORITY:
  69. CREATIONFLAGS = win32con.HIGH_PRIORITY_CLASS
  70. print "configured to run under high priority"
  71. BENCH_EXECONFIG = '_bench_windows_exe.txt'
  72. bench_exe = None
  73. def reference(progname):
  74. global bench_exe
  75. if not bench_exe:
  76. if os.path.exists(BENCH_EXECONFIG):
  77. progname = file(BENCH_EXECONFIG).read().strip()
  78. print "using %s instead of the system default" % progname
  79. bench_exe = progname
  80. return bench_exe
  81. def run_version_size(executable=reference('python'), *args):
  82. ver, size, dll = run_cmd('%s -c "import sys, os; print sys.version.split()[0], '
  83. 'os.path.getsize(sys.executable), sys.dllhandle"'
  84. % executable).split()
  85. size = int(size)
  86. try:
  87. import win32api
  88. except ImportError:
  89. pass
  90. else:
  91. size += os.path.getsize(win32api.GetModuleFileName(int(dll)))
  92. return ver, size
  93. def run_pystone(executable=reference('python'), n=0, rpy=False):
  94. if rpy:
  95. txt = run_cmd('%s pystone' % executable)
  96. else:
  97. argstr = PYSTONE_CMD % (str(n) and n or '')
  98. txt = run_cmd('%s -c "%s"' % (executable, argstr))
  99. res = get_result(txt, PYSTONE_PATTERN)
  100. print res
  101. return res
  102. def run_richards(executable=reference('python'), n=20, rpy=False):
  103. if rpy:
  104. txt = run_cmd('%s richards' % executable)
  105. else:
  106. argstr = RICHARDS_CMD % n
  107. txt = run_cmd('%s -c "%s"' % (executable, argstr))
  108. res = get_result(txt, RICHARDS_PATTERN)
  109. print res
  110. return res
  111. def get_executables():
  112. exes = [name for name in os.listdir('.') if name.endswith('.exe')]
  113. exes.sort()
  114. return exes
  115. STAT_FILE = '_bench_windows.dump'
  116. def load_stats(statfile=STAT_FILE):
  117. try:
  118. dic = pickle.load(file(statfile, 'rb'))
  119. except IOError:
  120. dic = {}
  121. return dic
  122. def save_stats(dic, statfile=STAT_FILE):
  123. pickle.dump(dic, file(statfile, 'wb'))
  124. HEADLINE = '''\
  125. executable richards pystone size (MB)'''
  126. FMT = '''\
  127. %-27s''' + '%5d %5.1fx' + ' %9.1f %5.1fx %5.3f'
  128. FMT2 = '''\
  129. %-27s''' + '%5.3f %5.1f/' + ' %9.1f %5.1f/ %5.3f'
  130. def main():
  131. print 'getting the richards reference'
  132. ref_rich = run_richards()
  133. print 'getting the pystone reference'
  134. ref_stone = run_pystone()
  135. resdic = {}
  136. prior = load_stats()
  137. for exe in get_executables():
  138. exename = os.path.splitext(exe)[0]
  139. mtime = os.path.getmtime(exe)
  140. size = os.path.getsize(exe)
  141. rpy = size < 500000
  142. key = md5.new(file(exe,'rb').read()).digest()
  143. if key in prior:
  144. print 'skipped', exename
  145. resdic[key] = prior[key][:2] + (exename, mtime, size)
  146. else:
  147. resdic[key] = (run_richards(exe, 2,rpy), run_pystone(exe, 20000, rpy),
  148. exename, mtime, size)
  149. prior[key] = resdic[key] # save result, temporarily
  150. save_stats(prior)
  151. save_stats(resdic) # save cleaned result
  152. res = [ (stone / rich, exe, size, rich, stone)
  153. for rich, stone, exe, mtime, size in resdic.values()]
  154. version, size = run_version_size()
  155. res.append( (ref_stone/ref_rich, 'python %s' % version, size, ref_rich, ref_stone) )
  156. res.sort()
  157. print HEADLINE
  158. for speed2, exe, size, rich, stone in res:
  159. if speed2 <= ref_stone/ref_rich:
  160. print FMT % (exe, rich, rich / ref_rich, stone, ref_stone / stone,
  161. size / float(1024 * 1024))
  162. else:
  163. print FMT2 % (exe, rich, ref_rich / rich, stone, stone / ref_stone,
  164. size / float(1024 * 1024))
  165. if __name__ == '__main__':
  166. main()