/scripts/circuits.bench

https://bitbucket.org/prologic/circuits/ · Unknown · 342 lines · 261 code · 81 blank · 0 comment · 0 complexity · 73b36338da7294751a3f3bbc33c6f871 MD5 · raw file

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # vim: set sw=3 sts=3 ts=3
  4. """(Tool) Bench Marking Tool
  5. THis tool does some simple benchmaking of the circuits library.
  6. """
  7. import sys
  8. import math
  9. import time
  10. import optparse
  11. try:
  12. import hotshot
  13. import hotshot.stats
  14. except ImportError:
  15. hostshot = None
  16. try:
  17. import psyco
  18. except ImportError:
  19. psyco = None
  20. from circuits import __version__ as systemVersion
  21. from circuits import handler, Event, Component, Bridge, Manager, Debugger
  22. USAGE = "%prog [options]"
  23. VERSION = "%prog v" + systemVersion
  24. ERRORS = [
  25. (0, "Cannot listen and connect at the same time!"),
  26. (1, "Invalid events spcified. Must be an integer."),
  27. (2, "Invalid time spcified. Must be an integer."),
  28. (3, "Invalid nthreads spcified. Must be an integer."),
  29. ]
  30. ###
  31. ### Functions
  32. ###
  33. def duration(seconds):
  34. days = int(seconds / 60 / 60 / 24)
  35. seconds = (seconds) % (60 * 60 * 24)
  36. hours = int((seconds / 60 / 60))
  37. seconds = (seconds) % (60 * 60)
  38. mins = int((seconds / 60))
  39. seconds = int((seconds) % (60))
  40. return (days, hours, mins, seconds)
  41. def parse_options():
  42. """parse_options() -> opts, args
  43. Parse the command-line options given returning both
  44. the parsed options and arguments.
  45. """
  46. parser = optparse.OptionParser(usage=USAGE, version=VERSION)
  47. parser.add_option("-l", "--listen",
  48. action="store_true", default=False, dest="listen",
  49. help="Listen on 0.0.0.0:8000 (UDP) to test remote events")
  50. parser.add_option("-w", "--wait",
  51. action="store_true", default=False, dest="wait",
  52. help="Wait for remote nodes to conenct")
  53. parser.add_option("-b", "--bind",
  54. action="store", type="string", default="0.0.0.0", dest="bind",
  55. help="Bind to address:[port] (UDP) to test remote events")
  56. parser.add_option("-c", "--concurrency",
  57. action="store", type="int", default=1, dest="concurrency",
  58. help="Set concurrency level")
  59. parser.add_option("-t", "--time",
  60. action="store", type="int", default=0, dest="time",
  61. help="Stop after specified elapsed seconds")
  62. parser.add_option("-e", "--events",
  63. action="store", type="int", default=0, dest="events",
  64. help="Stop after specified number of events")
  65. parser.add_option("-p", "--profile",
  66. action="store_true", default=False, dest="profile",
  67. help="Enable execution profiling support")
  68. parser.add_option("-m", "--mode",
  69. action="store", type="choice", default="speed", dest="mode",
  70. choices=["sync", "speed", "latency"],
  71. help="Operation mode")
  72. parser.add_option("-f", "--fill",
  73. action="store", type="int", default=0, dest="fill",
  74. help="No. of dummy events to fill queue with")
  75. parser.add_option("-d", "--debug",
  76. action="store_true", default=False, dest="debug",
  77. help="Enable debug mode")
  78. parser.add_option("-s", "--speed",
  79. action="store_true", default=False, dest="speed",
  80. help="Enable psyco (circuits on speed!)")
  81. parser.add_option("-o", "--output",
  82. action="store", default=None, dest="output",
  83. help="Specify output format")
  84. parser.add_option("-q", "--quiet",
  85. action="store_false", default=True, dest="verbose",
  86. help="Suppress output")
  87. opts, args = parser.parse_args()
  88. if opts.listen and args:
  89. parser.exit(ERRORS[0][0], ERRORS[0][1])
  90. return opts, args
  91. ###
  92. ### Events
  93. ###
  94. class Stop(Event): pass
  95. class Term(Event): pass
  96. class Hello(Event): pass
  97. class Received(Event): pass
  98. class Foo(Event): pass
  99. ###
  100. ### Components
  101. ###
  102. class Base(Component):
  103. def __init__(self, opts, *args, **kwargs):
  104. super(Base, self).__init__(*args, **kwargs)
  105. self.opts = opts
  106. class Sender(Base):
  107. concurrency = 1
  108. def received(self, message=""):
  109. self.fire(Hello("hello"))
  110. class Receiver(Base):
  111. def helo(self, address, port):
  112. self.fire(Hello("hello"))
  113. def hello(self, message=""):
  114. self.fire(Received(message))
  115. class SpeedTest(Base):
  116. def hello(self, message):
  117. self.fire(Hello(message))
  118. class LatencyTest(Base):
  119. t = None
  120. def received(self, message=""):
  121. print("Latency: %0.3f us" % ((time.time() - self.t) * 1e6))
  122. time.sleep(1)
  123. self.fire(Hello("hello"))
  124. def hello(self, message=""):
  125. self.t = time.time()
  126. self.fire(Received(message))
  127. class State(Base):
  128. done = False
  129. def stop(self):
  130. self.fire(Term())
  131. def term(self):
  132. self.done = True
  133. class Monitor(Base):
  134. sTime = sys.maxsize
  135. events = 0
  136. state = 0
  137. def helo(self, *args, **kwargs):
  138. if self.opts.verbose:
  139. print("Resetting sTime")
  140. self.sTime = time.time()
  141. @handler(filter=True)
  142. def event(self, *args, **kwargs):
  143. self.events += 1
  144. ###
  145. ### Main
  146. ###
  147. def main():
  148. opts, args = parse_options()
  149. if opts.speed and psyco:
  150. psyco.full()
  151. manager = Manager()
  152. monitor = Monitor(opts)
  153. manager += monitor
  154. state = State(opts)
  155. manager += state
  156. if opts.debug:
  157. manager += Debugger()
  158. if opts.listen or args:
  159. nodes = []
  160. if args:
  161. for node in args:
  162. if ":" in node:
  163. host, port = node.split(":")
  164. port = int(port)
  165. else:
  166. host = node
  167. port = 8000
  168. nodes.append((host, port))
  169. if opts.bind is not None:
  170. if ":" in opts.bind:
  171. address, port = opts.bind.split(":")
  172. port = int(port)
  173. else:
  174. address, port = opts.bind, 8000
  175. bridge = Bridge(bind=(address, port), nodes=nodes)
  176. manager += bridge
  177. if opts.mode.lower() == "speed":
  178. if opts.verbose:
  179. print("Setting up Speed Test...")
  180. if opts.concurrency > 1:
  181. for c in range(int(opts.concurrency)):
  182. manager += SpeedTest(opts, channel=c)
  183. else:
  184. manager += SpeedTest(opts)
  185. monitor.sTime = time.time()
  186. elif opts.mode.lower() == "latency":
  187. if opts.verbose:
  188. print("Setting up Latency Test...")
  189. manager += LatencyTest(opts)
  190. monitor.sTime = time.time()
  191. elif opts.listen:
  192. if opts.verbose:
  193. print("Setting up Receiver...")
  194. if opts.concurrency > 1:
  195. for c in range(int(opts.concurrency)):
  196. manager += Receiver(opts, channel=c)
  197. else:
  198. manager += Receiver(opts)
  199. elif args:
  200. if opts.verbose:
  201. print("Setting up Sender...")
  202. if opts.concurrency > 1:
  203. for c in range(int(opts.concurrency)):
  204. manager += Sender(opts, channel=c)
  205. else:
  206. manager += Sender(opts)
  207. else:
  208. if opts.verbose:
  209. print("Setting up Sender...")
  210. print("Setting up Receiver...")
  211. if opts.concurrency > 1:
  212. for c in range(int(opts.concurrency)):
  213. manager += Sender(channel=c)
  214. manager += Receiver(opts, channel=c)
  215. else:
  216. manager += Sender(opts)
  217. manager += Receiver(opts)
  218. monitor.sTime = time.time()
  219. if opts.profile:
  220. if hotshot:
  221. profiler = hotshot.Profile("bench.prof")
  222. profiler.start()
  223. if not opts.wait:
  224. if opts.concurrency > 1:
  225. for c in range(int(opts.concurrency)):
  226. manager.push(Hello("hello"), "hello", c)
  227. else:
  228. manager.push(Hello("hello"))
  229. while not state.done:
  230. try:
  231. manager.flush()
  232. for i in range(opts.fill):
  233. manager.push(Foo())
  234. if opts.events > 0 and monitor.events > opts.events:
  235. manager.push(Stop())
  236. if opts.time > 0 and (time.time() - monitor.sTime) > opts.time:
  237. manager.push(Stop())
  238. except KeyboardInterrupt:
  239. manager.push(Stop())
  240. if opts.verbose:
  241. print()
  242. eTime = time.time()
  243. tTime = eTime - monitor.sTime
  244. events = monitor.events
  245. speed = int(math.ceil(float(monitor.events) / tTime))
  246. if opts.output:
  247. print(opts.output % (events, speed, tTime))
  248. else:
  249. print("Total Events: %d (%d/s after %0.2fs)" % (events, speed, tTime))
  250. if opts.profile and hotshot:
  251. profiler.stop()
  252. profiler.close()
  253. stats = hotshot.stats.load("bench.prof")
  254. stats.strip_dirs()
  255. stats.sort_stats("time", "calls")
  256. stats.print_stats(20)
  257. ###
  258. ### Entry Point
  259. ###
  260. if __name__ == "__main__":
  261. main()