pystone.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. #! /usr/bin/python3.6
  2. """
  3. "PYSTONE" Benchmark Program
  4. Version: Python/1.2 (corresponds to C/1.1 plus 3 Pystone fixes)
  5. Author: Reinhold P. Weicker, CACM Vol 27, No 10, 10/84 pg. 1013.
  6. Translated from ADA to C by Rick Richardson.
  7. Every method to preserve ADA-likeness has been used,
  8. at the expense of C-ness.
  9. Translated from C to Python by Guido van Rossum.
  10. Version History:
  11. Version 1.1 corrects two bugs in version 1.0:
  12. First, it leaked memory: in Proc1(), NextRecord ends
  13. up having a pointer to itself. I have corrected this
  14. by zapping NextRecord.PtrComp at the end of Proc1().
  15. Second, Proc3() used the operator != to compare a
  16. record to None. This is rather inefficient and not
  17. true to the intention of the original benchmark (where
  18. a pointer comparison to None is intended; the !=
  19. operator attempts to find a method __cmp__ to do value
  20. comparison of the record). Version 1.1 runs 5-10
  21. percent faster than version 1.0, so benchmark figures
  22. of different versions can't be compared directly.
  23. Version 1.2 changes the division to floor division.
  24. Under Python 3 version 1.1 would use the normal division
  25. operator, resulting in some of the operations mistakenly
  26. yielding floats. Version 1.2 instead uses floor division
  27. making the benchmark an integer benchmark again.
  28. """
  29. LOOPS = 50000
  30. from time import time
  31. __version__ = "1.2"
  32. [Ident1, Ident2, Ident3, Ident4, Ident5] = range(1, 6)
  33. class Record:
  34. def __init__(self, PtrComp = None, Discr = 0, EnumComp = 0,
  35. IntComp = 0, StringComp = 0):
  36. self.PtrComp = PtrComp
  37. self.Discr = Discr
  38. self.EnumComp = EnumComp
  39. self.IntComp = IntComp
  40. self.StringComp = StringComp
  41. def copy(self):
  42. return Record(self.PtrComp, self.Discr, self.EnumComp,
  43. self.IntComp, self.StringComp)
  44. TRUE = 1
  45. FALSE = 0
  46. def main(loops=LOOPS):
  47. benchtime, stones = pystones(loops)
  48. print("Pystone(%s) time for %d passes = %g" % \
  49. (__version__, loops, benchtime))
  50. print("This machine benchmarks at %g pystones/second" % stones)
  51. def pystones(loops=LOOPS):
  52. return Proc0(loops)
  53. IntGlob = 0
  54. BoolGlob = FALSE
  55. Char1Glob = '\0'
  56. Char2Glob = '\0'
  57. Array1Glob = [0]*51
  58. Array2Glob = [x[:] for x in [Array1Glob]*51]
  59. PtrGlb = None
  60. PtrGlbNext = None
  61. def Proc0(loops=LOOPS):
  62. global IntGlob
  63. global BoolGlob
  64. global Char1Glob
  65. global Char2Glob
  66. global Array1Glob
  67. global Array2Glob
  68. global PtrGlb
  69. global PtrGlbNext
  70. starttime = time()
  71. for i in range(loops):
  72. pass
  73. nulltime = time() - starttime
  74. PtrGlbNext = Record()
  75. PtrGlb = Record()
  76. PtrGlb.PtrComp = PtrGlbNext
  77. PtrGlb.Discr = Ident1
  78. PtrGlb.EnumComp = Ident3
  79. PtrGlb.IntComp = 40
  80. PtrGlb.StringComp = "DHRYSTONE PROGRAM, SOME STRING"
  81. String1Loc = "DHRYSTONE PROGRAM, 1'ST STRING"
  82. Array2Glob[8][7] = 10
  83. starttime = time()
  84. for i in range(loops):
  85. Proc5()
  86. Proc4()
  87. IntLoc1 = 2
  88. IntLoc2 = 3
  89. String2Loc = "DHRYSTONE PROGRAM, 2'ND STRING"
  90. EnumLoc = Ident2
  91. BoolGlob = not Func2(String1Loc, String2Loc)
  92. while IntLoc1 < IntLoc2:
  93. IntLoc3 = 5 * IntLoc1 - IntLoc2
  94. IntLoc3 = Proc7(IntLoc1, IntLoc2)
  95. IntLoc1 = IntLoc1 + 1
  96. Proc8(Array1Glob, Array2Glob, IntLoc1, IntLoc3)
  97. PtrGlb = Proc1(PtrGlb)
  98. CharIndex = 'A'
  99. while CharIndex <= Char2Glob:
  100. if EnumLoc == Func1(CharIndex, 'C'):
  101. EnumLoc = Proc6(Ident1)
  102. CharIndex = chr(ord(CharIndex)+1)
  103. IntLoc3 = IntLoc2 * IntLoc1
  104. IntLoc2 = IntLoc3 // IntLoc1
  105. IntLoc2 = 7 * (IntLoc3 - IntLoc2) - IntLoc1
  106. IntLoc1 = Proc2(IntLoc1)
  107. benchtime = time() - starttime - nulltime
  108. if benchtime == 0.0:
  109. loopsPerBenchtime = 0.0
  110. else:
  111. loopsPerBenchtime = (loops / benchtime)
  112. return benchtime, loopsPerBenchtime
  113. def Proc1(PtrParIn):
  114. PtrParIn.PtrComp = NextRecord = PtrGlb.copy()
  115. PtrParIn.IntComp = 5
  116. NextRecord.IntComp = PtrParIn.IntComp
  117. NextRecord.PtrComp = PtrParIn.PtrComp
  118. NextRecord.PtrComp = Proc3(NextRecord.PtrComp)
  119. if NextRecord.Discr == Ident1:
  120. NextRecord.IntComp = 6
  121. NextRecord.EnumComp = Proc6(PtrParIn.EnumComp)
  122. NextRecord.PtrComp = PtrGlb.PtrComp
  123. NextRecord.IntComp = Proc7(NextRecord.IntComp, 10)
  124. else:
  125. PtrParIn = NextRecord.copy()
  126. NextRecord.PtrComp = None
  127. return PtrParIn
  128. def Proc2(IntParIO):
  129. IntLoc = IntParIO + 10
  130. while 1:
  131. if Char1Glob == 'A':
  132. IntLoc = IntLoc - 1
  133. IntParIO = IntLoc - IntGlob
  134. EnumLoc = Ident1
  135. if EnumLoc == Ident1:
  136. break
  137. return IntParIO
  138. def Proc3(PtrParOut):
  139. global IntGlob
  140. if PtrGlb is not None:
  141. PtrParOut = PtrGlb.PtrComp
  142. else:
  143. IntGlob = 100
  144. PtrGlb.IntComp = Proc7(10, IntGlob)
  145. return PtrParOut
  146. def Proc4():
  147. global Char2Glob
  148. BoolLoc = Char1Glob == 'A'
  149. BoolLoc = BoolLoc or BoolGlob
  150. Char2Glob = 'B'
  151. def Proc5():
  152. global Char1Glob
  153. global BoolGlob
  154. Char1Glob = 'A'
  155. BoolGlob = FALSE
  156. def Proc6(EnumParIn):
  157. EnumParOut = EnumParIn
  158. if not Func3(EnumParIn):
  159. EnumParOut = Ident4
  160. if EnumParIn == Ident1:
  161. EnumParOut = Ident1
  162. elif EnumParIn == Ident2:
  163. if IntGlob > 100:
  164. EnumParOut = Ident1
  165. else:
  166. EnumParOut = Ident4
  167. elif EnumParIn == Ident3:
  168. EnumParOut = Ident2
  169. elif EnumParIn == Ident4:
  170. pass
  171. elif EnumParIn == Ident5:
  172. EnumParOut = Ident3
  173. return EnumParOut
  174. def Proc7(IntParI1, IntParI2):
  175. IntLoc = IntParI1 + 2
  176. IntParOut = IntParI2 + IntLoc
  177. return IntParOut
  178. def Proc8(Array1Par, Array2Par, IntParI1, IntParI2):
  179. global IntGlob
  180. IntLoc = IntParI1 + 5
  181. Array1Par[IntLoc] = IntParI2
  182. Array1Par[IntLoc+1] = Array1Par[IntLoc]
  183. Array1Par[IntLoc+30] = IntLoc
  184. for IntIndex in range(IntLoc, IntLoc+2):
  185. Array2Par[IntLoc][IntIndex] = IntLoc
  186. Array2Par[IntLoc][IntLoc-1] = Array2Par[IntLoc][IntLoc-1] + 1
  187. Array2Par[IntLoc+20][IntLoc] = Array1Par[IntLoc]
  188. IntGlob = 5
  189. def Func1(CharPar1, CharPar2):
  190. CharLoc1 = CharPar1
  191. CharLoc2 = CharLoc1
  192. if CharLoc2 != CharPar2:
  193. return Ident1
  194. else:
  195. return Ident2
  196. def Func2(StrParI1, StrParI2):
  197. IntLoc = 1
  198. while IntLoc <= 1:
  199. if Func1(StrParI1[IntLoc], StrParI2[IntLoc+1]) == Ident1:
  200. CharLoc = 'A'
  201. IntLoc = IntLoc + 1
  202. if CharLoc >= 'W' and CharLoc <= 'Z':
  203. IntLoc = 7
  204. if CharLoc == 'X':
  205. return TRUE
  206. else:
  207. if StrParI1 > StrParI2:
  208. IntLoc = IntLoc + 7
  209. return TRUE
  210. else:
  211. return FALSE
  212. def Func3(EnumParIn):
  213. EnumLoc = EnumParIn
  214. if EnumLoc == Ident3: return TRUE
  215. return FALSE
  216. if __name__ == '__main__':
  217. import sys
  218. def error(msg):
  219. print(msg, end=' ', file=sys.stderr)
  220. print("usage: %s [number_of_loops]" % sys.argv[0], file=sys.stderr)
  221. sys.exit(100)
  222. nargs = len(sys.argv) - 1
  223. if nargs > 1:
  224. error("%d arguments are too many;" % nargs)
  225. elif nargs == 1:
  226. try: loops = int(sys.argv[1])
  227. except ValueError:
  228. error("Invalid argument %r;" % sys.argv[1])
  229. else:
  230. loops = LOOPS
  231. main(loops)