benchmarking.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3. import sys
  4. import time
  5. import gc
  6. from functools import wraps
  7. #------------------------------------------------------------------------------
  8. # [ timer function decorator ]
  9. # runs timed repetitions of the decorated function in a single trial
  10. # default is 100,000 repetitions in the trial
  11. # reports the results of the trial
  12. # Usage example:
  13. # from Naked.toolshed.benchmarking import timer
  14. # @timer
  15. # def myfunction():
  16. #------------------------------------------------------------------------------
  17. def timer(func, repetitions=100000):
  18. @wraps(func)
  19. def wrapper(*args, **kwargs):
  20. sys.stdout.write("Starting " + str(repetitions) + " repetitions of " + func.__name__ + "()...")
  21. sys.stdout.flush()
  22. print(" ")
  23. # disable garbage collection
  24. gc.collect()
  25. gc.disable()
  26. start = time.time()
  27. for x in range(repetitions):
  28. result = func(*args, **kwargs)
  29. end = time.time()
  30. gc.enable() # re-enable garbage collection
  31. gc.collect()
  32. print(str(repetitions) + " repetitions of " + func.__name__ + " : " + str(end-start) + " sec")
  33. return result
  34. return wrapper
  35. #------------------------------------------------------------------------------
  36. # [ timer_X function decorators ]
  37. # replicate the above decorator with different number of repetitions
  38. #------------------------------------------------------------------------------
  39. def timer_10(func, repetitions=10):
  40. @wraps(func)
  41. def wrapper(*args, **kwargs):
  42. sys.stdout.write("Starting " + str(repetitions) + " repetitions of " + func.__name__ + "()...")
  43. sys.stdout.flush()
  44. print(" ")
  45. # disable garbage collection
  46. gc.collect()
  47. gc.disable()
  48. start = time.time()
  49. for x in range(repetitions):
  50. result = func(*args, **kwargs)
  51. end = time.time()
  52. gc.enable() # re-enable garbage collection
  53. gc.collect()
  54. print(str(repetitions) + " repetitions of " + func.__name__ + " : " + str(end-start) + " sec")
  55. return result
  56. return wrapper
  57. def timer_100(func, repetitions=100):
  58. @wraps(func)
  59. def wrapper(*args, **kwargs):
  60. sys.stdout.write("Starting " + str(repetitions) + " repetitions of " + func.__name__ + "()...")
  61. sys.stdout.flush()
  62. print(" ")
  63. # disable garbage collection
  64. gc.collect()
  65. gc.disable()
  66. start = time.time()
  67. for x in range(repetitions):
  68. result = func(*args, **kwargs)
  69. end = time.time()
  70. gc.enable() # re-enable garbage collection
  71. gc.collect()
  72. print(str(repetitions) + " repetitions of " + func.__name__ + " : " + str(end-start) + " sec")
  73. return result
  74. return wrapper
  75. def timer_1k(func, repetitions=1000):
  76. @wraps(func)
  77. def wrapper(*args, **kwargs):
  78. sys.stdout.write("Starting " + str(repetitions) + " repetitions of " + func.__name__ + "()...")
  79. sys.stdout.flush()
  80. print(" ")
  81. # disable garbage collection
  82. gc.collect()
  83. gc.disable()
  84. start = time.time()
  85. for x in range(repetitions):
  86. result = func(*args, **kwargs)
  87. end = time.time()
  88. gc.enable() # re-enable garbage collection
  89. gc.collect()
  90. print(str(repetitions) + " repetitions of " + func.__name__ + " : " + str(end-start) + " sec")
  91. return result
  92. return wrapper
  93. def timer_10k(func, repetitions=10000):
  94. @wraps(func)
  95. def wrapper(*args, **kwargs):
  96. sys.stdout.write("Starting " + str(repetitions) + " repetitions of " + func.__name__ + "()...")
  97. sys.stdout.flush()
  98. print(" ")
  99. # disable garbage collection
  100. gc.collect()
  101. gc.disable()
  102. start = time.time()
  103. for x in range(repetitions):
  104. result = func(*args, **kwargs)
  105. end = time.time()
  106. gc.enable() # re-enable garbage collection
  107. gc.collect()
  108. print(str(repetitions) + " repetitions of " + func.__name__ + " : " + str(end-start) + " sec")
  109. return result
  110. return wrapper
  111. def timer_1m(func, repetitions=1000000):
  112. @wraps(func)
  113. def wrapper(*args, **kwargs):
  114. sys.stdout.write("Starting " + str(repetitions) + " repetitions of " + func.__name__ + "()...")
  115. sys.stdout.flush()
  116. print(" ")
  117. # disable garbage collection
  118. gc.collect()
  119. gc.disable()
  120. start = time.time()
  121. for x in range(repetitions):
  122. result = func(*args, **kwargs)
  123. end = time.time()
  124. gc.enable() # re-enable garbage collection
  125. gc.collect()
  126. print(str(repetitions) + " repetitions of " + func.__name__ + " : " + str(end-start) + " sec")
  127. return result
  128. return wrapper
  129. #------------------------------------------------------------------------------
  130. # [ timer_trials_benchmark decorator function ]
  131. # time a function and compare to a benchmark function
  132. # default is 10 trials x 100,000 repetitions/trial for each function
  133. # Results:
  134. # - Mean of the 10 trials of the test function
  135. # - standard deviation of the 10 trials (if numpy is available)
  136. # - result for 100,000 repetitions of the benchmark function
  137. # - ratio of the test : benchmark function results
  138. # Usage example:
  139. # from Naked.toolshed.benchmarking import timer_trials_benchmark
  140. # @timer_trials_benchmark
  141. # def myfunction():
  142. #------------------------------------------------------------------------------
  143. def timer_trials_benchmark(func, repetitions=100000, trials=10):
  144. @wraps(func)
  145. def wrapper(*args, **kwargs):
  146. sys.stdout.write("Starting timed trials of " + func.__name__ + "()")
  147. sys.stdout.flush()
  148. result_list = []
  149. benchmark_list = []
  150. # disable garbage collection
  151. gc.collect()
  152. gc.disable()
  153. for x in range(trials):
  154. # test function
  155. start = time.time()
  156. for y in range(repetitions):
  157. func(*args, **kwargs)
  158. end = time.time()
  159. result = func(*args, **kwargs)
  160. result_list.append(end-start)
  161. # benchmark function
  162. L = []
  163. start2 = time.time()
  164. for j in range(repetitions):
  165. for i in range(10):
  166. L.append(i)
  167. end2 = time.time()
  168. benchmark_list.append(end2 - start2)
  169. sys.stdout.write(".")
  170. sys.stdout.flush()
  171. gc.enable() # re-enable garbage collection
  172. gc.collect()
  173. print(" ")
  174. n = 1
  175. for run in result_list:
  176. print("Trial " + str(n) + ":\t" + str(run))
  177. n += 1
  178. print("-"*50)
  179. mean = sum(result_list)/len(result_list)
  180. mean_benchmark = sum(benchmark_list)/len(benchmark_list)
  181. print("Mean for " + str(repetitions) + " repetitions: " + str(mean) + " sec")
  182. try:
  183. import numpy as np
  184. array = np.array(result_list)
  185. print( "Standard Deviation: " + str(np.std(array)))
  186. except ImportError as ie:
  187. pass
  188. print("Mean per repetition: " + str(mean/repetitions) + " sec")
  189. print("Mean for " + str(repetitions) + " of benchmark function:" + str(mean_benchmark) + " sec")
  190. print("Ratio: " + str(mean/mean_benchmark))
  191. return result
  192. return wrapper
  193. #------------------------------------------------------------------------------
  194. # [ timer_trials_benchmark_X decorators ]
  195. # additional benchmark decorators that replicate the above function with different # repetitions
  196. #------------------------------------------------------------------------------
  197. def timer_trials_benchmark_10(func, repetitions=10, trials=10):
  198. @wraps(func)
  199. def wrapper(*args, **kwargs):
  200. sys.stdout.write("Starting timed trials of " + func.__name__ + "()")
  201. sys.stdout.flush()
  202. result_list = []
  203. benchmark_list = []
  204. # disable garbage collection
  205. gc.collect()
  206. gc.disable()
  207. for x in range(trials):
  208. # test function
  209. start = time.time()
  210. for y in range(repetitions):
  211. func(*args, **kwargs)
  212. end = time.time()
  213. result = func(*args, **kwargs)
  214. result_list.append(end-start)
  215. # benchmark function
  216. L = []
  217. start2 = time.time()
  218. for j in range(repetitions):
  219. for i in range(10):
  220. L.append(i)
  221. end2 = time.time()
  222. benchmark_list.append(end2 - start2)
  223. sys.stdout.write(".")
  224. sys.stdout.flush()
  225. gc.enable() # re-enable garbage collection
  226. gc.collect()
  227. print(" ")
  228. n = 1
  229. for run in result_list:
  230. print("Trial " + str(n) + ":\t" + str(run))
  231. n += 1
  232. print("-"*50)
  233. mean = sum(result_list)/len(result_list)
  234. mean_benchmark = sum(benchmark_list)/len(benchmark_list)
  235. print("Mean for " + str(repetitions) + " repetitions: " + str(mean) + " sec")
  236. try:
  237. import numpy as np
  238. array = np.array(result_list)
  239. print( "Standard Deviation: " + str(np.std(array)))
  240. except ImportError as ie:
  241. pass
  242. print("Mean per repetition: " + str(mean/repetitions) + " sec")
  243. print("Mean for " + str(repetitions) + " of benchmark function:" + str(mean_benchmark) + " sec")
  244. print("Ratio: " + str(mean/mean_benchmark))
  245. return result
  246. return wrapper
  247. def timer_trials_benchmark_100(func, repetitions=100, trials=10):
  248. @wraps(func)
  249. def wrapper(*args, **kwargs):
  250. sys.stdout.write("Starting timed trials of " + func.__name__ + "()")
  251. sys.stdout.flush()
  252. result_list = []
  253. benchmark_list = []
  254. # disable garbage collection
  255. gc.collect()
  256. gc.disable()
  257. for x in range(trials):
  258. # test function
  259. start = time.time()
  260. for y in range(repetitions):
  261. func(*args, **kwargs)
  262. end = time.time()
  263. result = func(*args, **kwargs)
  264. result_list.append(end-start)
  265. # benchmark function
  266. L = []
  267. start2 = time.time()
  268. for j in range(repetitions):
  269. for i in range(10):
  270. L.append(i)
  271. end2 = time.time()
  272. benchmark_list.append(end2 - start2)
  273. sys.stdout.write(".")
  274. sys.stdout.flush()
  275. gc.enable() # re-enable garbage collection
  276. gc.collect()
  277. print(" ")
  278. n = 1
  279. for run in result_list:
  280. print("Trial " + str(n) + ":\t" + str(run))
  281. n += 1
  282. print("-"*50)
  283. mean = sum(result_list)/len(result_list)
  284. mean_benchmark = sum(benchmark_list)/len(benchmark_list)
  285. print("Mean for " + str(repetitions) + " repetitions: " + str(mean) + " sec")
  286. try:
  287. import numpy as np
  288. array = np.array(result_list)
  289. print( "Standard Deviation: " + str(np.std(array)))
  290. except ImportError as ie:
  291. pass
  292. print("Mean per repetition: " + str(mean/repetitions) + " sec")
  293. print("Mean for " + str(repetitions) + " of benchmark function:" + str(mean_benchmark) + " sec")
  294. print("Ratio: " + str(mean/mean_benchmark))
  295. return result
  296. return wrapper
  297. def timer_trials_benchmark_1k(func, repetitions=1000, trials=10):
  298. @wraps(func)
  299. def wrapper(*args, **kwargs):
  300. sys.stdout.write("Starting timed trials of " + func.__name__ + "()")
  301. sys.stdout.flush()
  302. result_list = []
  303. benchmark_list = []
  304. # disable garbage collection
  305. gc.collect()
  306. gc.disable()
  307. for x in range(trials):
  308. # test function
  309. start = time.time()
  310. for y in range(repetitions):
  311. func(*args, **kwargs)
  312. end = time.time()
  313. result = func(*args, **kwargs)
  314. result_list.append(end-start)
  315. # benchmark function
  316. L = []
  317. start2 = time.time()
  318. for j in range(repetitions):
  319. for i in range(10):
  320. L.append(i)
  321. end2 = time.time()
  322. benchmark_list.append(end2 - start2)
  323. sys.stdout.write(".")
  324. sys.stdout.flush()
  325. gc.enable() # re-enable garbage collection
  326. gc.collect()
  327. print(" ")
  328. n = 1
  329. for run in result_list:
  330. print("Trial " + str(n) + ":\t" + str(run))
  331. n += 1
  332. print("-"*50)
  333. mean = sum(result_list)/len(result_list)
  334. mean_benchmark = sum(benchmark_list)/len(benchmark_list)
  335. print("Mean for " + str(repetitions) + " repetitions: " + str(mean) + " sec")
  336. try:
  337. import numpy as np
  338. array = np.array(result_list)
  339. print( "Standard Deviation: " + str(np.std(array)))
  340. except ImportError as ie:
  341. pass
  342. print("Mean per repetition: " + str(mean/repetitions) + " sec")
  343. print("Mean for " + str(repetitions) + " of benchmark function:" + str(mean_benchmark) + " sec")
  344. print("Ratio: " + str(mean/mean_benchmark))
  345. return result
  346. return wrapper
  347. def timer_trials_benchmark_10k(func, repetitions=10000, trials=10):
  348. @wraps(func)
  349. def wrapper(*args, **kwargs):
  350. sys.stdout.write("Starting timed trials of " + func.__name__ + "()")
  351. sys.stdout.flush()
  352. result_list = []
  353. benchmark_list = []
  354. # disable garbage collection
  355. gc.collect()
  356. gc.disable()
  357. for x in range(trials):
  358. # test function
  359. start = time.time()
  360. for y in range(repetitions):
  361. func(*args, **kwargs)
  362. end = time.time()
  363. result = func(*args, **kwargs)
  364. result_list.append(end-start)
  365. # benchmark function
  366. L = []
  367. start2 = time.time()
  368. for j in range(repetitions):
  369. for i in range(10):
  370. L.append(i)
  371. end2 = time.time()
  372. benchmark_list.append(end2 - start2)
  373. sys.stdout.write(".")
  374. sys.stdout.flush()
  375. gc.enable() # re-enable garbage collection
  376. gc.collect()
  377. print(" ")
  378. n = 1
  379. for run in result_list:
  380. print("Trial " + str(n) + ":\t" + str(run))
  381. n += 1
  382. print("-"*50)
  383. mean = sum(result_list)/len(result_list)
  384. mean_benchmark = sum(benchmark_list)/len(benchmark_list)
  385. print("Mean for " + str(repetitions) + " repetitions: " + str(mean) + " sec")
  386. try:
  387. import numpy as np
  388. array = np.array(result_list)
  389. print( "Standard Deviation: " + str(np.std(array)))
  390. except ImportError as ie:
  391. pass
  392. print("Mean per repetition: " + str(mean/repetitions) + " sec")
  393. print("Mean for " + str(repetitions) + " of benchmark function:" + str(mean_benchmark) + " sec")
  394. print("Ratio: " + str(mean/mean_benchmark))
  395. return result
  396. return wrapper
  397. def timer_trials_benchmark_1m(func, repetitions=1000000, trials=10):
  398. @wraps(func)
  399. def wrapper(*args, **kwargs):
  400. sys.stdout.write("Starting timed trials of " + func.__name__ + "()")
  401. sys.stdout.flush()
  402. result_list = []
  403. benchmark_list = []
  404. # disable garbage collection
  405. gc.collect()
  406. gc.disable()
  407. for x in range(trials):
  408. # test function
  409. start = time.time()
  410. for y in range(repetitions):
  411. func(*args, **kwargs)
  412. end = time.time()
  413. result = func(*args, **kwargs)
  414. result_list.append(end-start)
  415. # benchmark function
  416. L = []
  417. start2 = time.time()
  418. for j in range(repetitions):
  419. for i in range(10):
  420. L.append(i)
  421. end2 = time.time()
  422. benchmark_list.append(end2 - start2)
  423. sys.stdout.write(".")
  424. sys.stdout.flush()
  425. gc.enable() # re-enable garbage collection
  426. gc.collect()
  427. print(" ")
  428. n = 1
  429. for run in result_list:
  430. print("Trial " + str(n) + ":\t" + str(run))
  431. n += 1
  432. print("-"*50)
  433. mean = sum(result_list)/len(result_list)
  434. mean_benchmark = sum(benchmark_list)/len(benchmark_list)
  435. print("Mean for " + str(repetitions) + " repetitions: " + str(mean) + " sec")
  436. try:
  437. import numpy as np
  438. array = np.array(result_list)
  439. print( "Standard Deviation: " + str(np.std(array)))
  440. except ImportError as ie:
  441. pass
  442. print("Mean per repetition: " + str(mean/repetitions) + " sec")
  443. print("Mean for " + str(repetitions) + " of benchmark function:" + str(mean_benchmark) + " sec")
  444. print("Ratio: " + str(mean/mean_benchmark))
  445. return result
  446. return wrapper
  447. if __name__ == '__main__':
  448. pass