[pypy-svn] r71810 - in pypy/benchmarks: . own own/twisted unladen_swallow
fijal at codespeak.net
fijal at codespeak.net
Fri Mar 5 17:20:24 CET 2010
Author: fijal
Date: Fri Mar 5 17:20:22 2010
New Revision: 71810
Added:
pypy/benchmarks/own/twisted/
pypy/benchmarks/own/twisted/TODO
pypy/benchmarks/own/twisted/accepts.py (contents, props changed)
pypy/benchmarks/own/twisted/all.py (contents, props changed)
pypy/benchmarks/own/twisted/benchlib.py (contents, props changed)
pypy/benchmarks/own/twisted/iteration.py (contents, props changed)
pypy/benchmarks/own/twisted/names.py (contents, props changed)
pypy/benchmarks/own/twisted/pb.py (contents, props changed)
pypy/benchmarks/own/twisted/tcp.py (contents, props changed)
pypy/benchmarks/own/twisted/threads.py (contents, props changed)
pypy/benchmarks/own/twisted/web.py (contents, props changed)
Removed:
pypy/benchmarks/own/twisted_benchlib.py
pypy/benchmarks/own/twisted_iteration.py
pypy/benchmarks/own/twisted_names.py
pypy/benchmarks/own/twisted_web.py
Modified:
pypy/benchmarks/benchmarks.py
pypy/benchmarks/unladen_swallow/perf.py
Log:
Import twisted benchmarks from their official place. Kill our edited versions.
By default we run 3 iterations of warmup + 10 iterations of normal, until
we have a better metric, that's probably fine
Modified: pypy/benchmarks/benchmarks.py
==============================================================================
--- pypy/benchmarks/benchmarks.py (original)
+++ pypy/benchmarks/benchmarks.py Fri Mar 5 17:20:22 2010
@@ -17,22 +17,34 @@
d[BM.func_name] = BM
-TWISTED = [relative('lib/twisted-trunk'), relative('lib/zope.interface-3.5.3/src')]
+def _register_new_bm_twisted(name, bm_name, d, **opts):
+ def Measure(python, options):
+ def parser(line):
+ number = float(line.split(" ")[0])
+ return 3000/number
+ bm_path = relative('own', 'twisted', name + '.py')
+ return MeasureGeneric(python, options, bm_path, parser=parser, **opts)
+ Measure.func_name = 'Measure' + name.capitalize()
+
+ def BM(*args, **kwds):
+ return SimpleBenchmark(Measure, *args, **kwds)
+ BM.func_name = 'BM_' + bm_name
+
+ d[BM.func_name] = BM
+
+TWISTED = [relative('lib/twisted-trunk'), relative('lib/zope.interface-3.5.3/src'), relative('own/twisted')]
opts = {
'gcbench' : {'iteration_scaling' : .10},
- 'twisted_iteration': {'iteration_scaling': .10,
- 'bm_env': {'PYTHONPATH': ':'.join(TWISTED)}},
- 'twisted_web': {'iteration_scaling': .10,
- 'bm_env': {'PYTHONPATH': ':'.join(TWISTED)}},
- 'twisted_names': {'iteration_scaling': .10,
- 'bm_env': {'PYTHONPATH': ':'.join(TWISTED)}},
}
for name in ['float', 'nbody_modified', 'meteor-contest', 'fannkuch',
- 'spectral-norm', 'chaos', 'telco', 'gcbench',
- 'twisted_iteration', 'twisted_web', 'twisted_names']:
+ 'spectral-norm', 'chaos', 'telco']:
_register_new_bm(name, name, globals(), **opts.get(name, {}))
+for name in ['web', 'names', 'accepts', 'iteration', 'tcp', 'pb']:
+ _register_new_bm_twisted(name, 'twisted_' + name,
+ globals(), bm_env={'PYTHONPATH': ':'.join(TWISTED)},
+ iteration_scaling=.20)
_register_new_bm('spitfire', 'spitfire', globals(),
extra_args=['--benchmark=spitfire_o4'])
_register_new_bm('spitfire', 'spitfire_cstringio', globals(),
Added: pypy/benchmarks/own/twisted/TODO
==============================================================================
--- (empty file)
+++ pypy/benchmarks/own/twisted/TODO Fri Mar 5 17:20:22 2010
@@ -0,0 +1,2 @@
+Debug dns slowdown over time
+Add an AMP benchmark
Added: pypy/benchmarks/own/twisted/accepts.py
==============================================================================
--- (empty file)
+++ pypy/benchmarks/own/twisted/accepts.py Fri Mar 5 17:20:22 2010
@@ -0,0 +1,55 @@
+
+from __future__ import division
+
+from twisted.internet.protocol import ServerFactory, ClientFactory, Protocol
+from twisted.internet.error import ConnectionClosed
+from twisted.internet.defer import Deferred
+
+from benchlib import Client, driver
+
+
+class Client(Client):
+ def __init__(self, reactor, portNumber):
+ super(Client, self).__init__(reactor)
+ self._portNumber = portNumber
+ self._factory = ClientFactory()
+
+
+ def _request(self):
+ finished = Deferred()
+ factory = ClientFactory()
+ factory.protocol = Protocol
+ factory.clientConnectionLost = factory.clientConnectionFailed = lambda connector, reason: finished.errback(reason)
+ finished.addErrback(self._filterFinished)
+ self._reactor.connectTCP('127.0.0.1', self._portNumber, factory)
+ finished.addCallback(self._continue)
+ finished.addErrback(self._stop)
+
+
+ def _filterFinished(self, reason):
+ reason.trap(ConnectionClosed)
+
+
+class CloseConnection(Protocol):
+ def makeConnection(self, transport):
+ transport.loseConnection()
+
+
+
+def main(reactor, duration):
+ concurrency = 50
+
+ factory = ServerFactory()
+ factory.protocol = CloseConnection
+ port = reactor.listenTCP(0, factory)
+
+ client = Client(reactor, port.getHost().port)
+ d = client.run(concurrency, duration)
+ return d
+
+
+
+if __name__ == '__main__':
+ import sys
+ import accepts
+ driver(accepts.main, sys.argv)
Added: pypy/benchmarks/own/twisted/all.py
==============================================================================
--- (empty file)
+++ pypy/benchmarks/own/twisted/all.py Fri Mar 5 17:20:22 2010
@@ -0,0 +1,8 @@
+
+from benchlib import multidriver
+
+import accepts, tcp, iteration, names, threads, web, pb
+
+if __name__ == '__main__':
+ multidriver(
+ accepts.main, tcp.main, iteration.main, names.main, threads.main, web.main, pb.main)
Added: pypy/benchmarks/own/twisted/benchlib.py
==============================================================================
--- (empty file)
+++ pypy/benchmarks/own/twisted/benchlib.py Fri Mar 5 17:20:22 2010
@@ -0,0 +1,87 @@
+
+import sys
+from twisted.internet.defer import Deferred
+from twisted.internet import reactor
+from twisted.python import log
+
+class Client(object):
+ def __init__(self, reactor):
+ self._reactor = reactor
+ self._requestCount = 0
+
+ def run(self, concurrency, duration):
+ self._reactor.callLater(duration, self._stop, None)
+ self._finished = Deferred()
+ for i in range(concurrency):
+ self._request()
+ return self._finished
+
+ def _continue(self, ignored):
+ self._requestCount += 1
+ if self._finished is not None:
+ self._request()
+
+ def _stop(self, reason):
+ if self._finished is not None:
+ finished = self._finished
+ self._finished = None
+ if reason is not None:
+ finished.errback(reason)
+ else:
+ finished.callback(self._requestCount)
+
+PRINT_TEMPL = ('%(stats)s %(name)s/sec (%(count)s %(name)s '
+ 'in %(duration)s seconds)')
+
+def benchmark_report(acceptCount, duration, name):
+ print PRINT_TEMPL % {
+ 'stats' : acceptCount / duration,
+ 'name' : name,
+ 'count' : acceptCount,
+ 'duration' : duration
+ }
+
+def setup_driver(f, argv, reactor):
+ from twisted.python.usage import Options
+
+ class BenchmarkOptions(Options):
+ optParameters = [
+ ('iterations', 'n', 1, 'number of iterations', int),
+ ('duration', 'd', 5, 'duration of each iteration', float),
+ ('warmup', 'w', 3, 'number of warmup iterations', int),
+ ]
+
+ options = BenchmarkOptions()
+ options.parseOptions(argv[1:])
+ duration = options['duration']
+ jobs = [f] * options['iterations']
+ d = Deferred()
+ def work(res, counter):
+ try:
+ f = jobs.pop()
+ except IndexError:
+ d.callback(None)
+ else:
+ next = f(reactor, duration)
+ if counter <= 0:
+ next.addCallback(benchmark_report, duration, f.__module__)
+ next.addCallbacks(work, d.errback, (counter - 1,))
+ work(None, options['warmup'])
+ return d
+
+def driver(f, argv):
+ d = setup_driver(f, argv, reactor)
+ d.addErrback(log.err)
+ reactor.callWhenRunning(d.addBoth, lambda ign: reactor.stop())
+ reactor.run()
+
+def multidriver(*f):
+ jobs = iter(f)
+ def work():
+ for job in jobs:
+ d = setup_driver(job, sys.argv, reactor)
+ d.addCallback(lambda ignored: work())
+ return
+ reactor.stop()
+ reactor.callWhenRunning(work)
+ reactor.run()
Added: pypy/benchmarks/own/twisted/iteration.py
==============================================================================
--- (empty file)
+++ pypy/benchmarks/own/twisted/iteration.py Fri Mar 5 17:20:22 2010
@@ -0,0 +1,25 @@
+
+from __future__ import division
+
+from benchlib import Client, driver
+
+
+class Client(Client):
+ def _request(self):
+ self._reactor.callLater(0.0, self._continue, None)
+
+
+
+def main(reactor, duration):
+ concurrency = 10
+
+ client = Client(reactor)
+ d = client.run(concurrency, duration)
+ return d
+
+
+
+if __name__ == '__main__':
+ import sys
+ import iteration
+ driver(iteration.main, sys.argv)
Added: pypy/benchmarks/own/twisted/names.py
==============================================================================
--- (empty file)
+++ pypy/benchmarks/own/twisted/names.py Fri Mar 5 17:20:22 2010
@@ -0,0 +1,47 @@
+
+from __future__ import division
+
+from twisted.names.dns import DNSDatagramProtocol
+from twisted.names.server import DNSServerFactory
+from twisted.names import hosts, client
+
+from benchlib import Client, driver
+
+
+class Client(Client):
+ def __init__(self, reactor, portNumber, timeout):
+ self._resolver = client.Resolver(servers=[('127.0.0.1', portNumber)])
+ self._timeout = timeout
+ super(Client, self).__init__(reactor)
+
+
+ def _request(self):
+ d = self._resolver.lookupAddress(
+ 'localhost', timeout=(self._timeout,))
+ d.addCallback(self._continue)
+ d.addErrback(self._stop)
+
+
+
+
+def main(reactor, duration):
+ concurrency = 10
+
+ controller = DNSServerFactory([hosts.Resolver()])
+ port = reactor.listenUDP(0, DNSDatagramProtocol(controller))
+ # Have queries time out no sooner than the duration of this benchmark so
+ # we don't have to deal with retries or timeout errors.
+ client = Client(reactor, port.getHost().port, duration)
+ d = client.run(concurrency, duration)
+ def cleanup(passthrough):
+ d = port.stopListening()
+ d.addCallback(lambda ign: passthrough)
+ return d
+ d.addBoth(cleanup)
+ return d
+
+
+if __name__ == '__main__':
+ import sys
+ import names
+ driver(names.main, sys.argv)
Added: pypy/benchmarks/own/twisted/pb.py
==============================================================================
--- (empty file)
+++ pypy/benchmarks/own/twisted/pb.py Fri Mar 5 17:20:22 2010
@@ -0,0 +1,61 @@
+
+"""
+Benchmark for Twisted Spread.
+"""
+
+from __future__ import division
+
+from twisted.spread.pb import PBServerFactory, PBClientFactory, Root
+
+from benchlib import Client, driver
+
+
+class BenchRoot(Root):
+ def remote_discard(self, argument):
+ pass
+
+
+
+class Client(Client):
+ _structure = [
+ 'hello' * 100,
+ {'foo': 'bar',
+ 'baz': 100,
+ u'these are bytes': (1, 2, 3)}]
+
+ def __init__(self, reactor, port):
+ super(Client, self).__init__(reactor)
+ self._port = port
+
+
+ def run(self, *args, **kwargs):
+ def connected(reference):
+ self._reference = reference
+ return super(Client, self).run(*args, **kwargs)
+ client = PBClientFactory()
+ d = client.getRootObject()
+ d.addCallback(connected)
+ self._reactor.connectTCP('127.0.0.1', self._port, client)
+ return d
+
+
+ def _request(self):
+ d = self._reference.callRemote('discard', self._structure)
+ d.addCallback(self._continue)
+ d.addErrback(self._stop)
+
+
+def main(reactor, duration):
+ concurrency = 15
+
+ server = PBServerFactory(BenchRoot())
+ port = reactor.listenTCP(0, server)
+ client = Client(reactor, port.getHost().port)
+ d = client.run(concurrency, duration)
+ return d
+
+
+if __name__ == '__main__':
+ import sys
+ import pb
+ driver(pb.main, sys.argv)
Added: pypy/benchmarks/own/twisted/tcp.py
==============================================================================
--- (empty file)
+++ pypy/benchmarks/own/twisted/tcp.py Fri Mar 5 17:20:22 2010
@@ -0,0 +1,93 @@
+
+"""
+This benchmarks runs a trivial Twisted TCP echo server and a client pumps as
+much data to it as it can in a fixed period of time.
+
+The size of the string passed to each write call may play a significant
+factor in the performance of this benchmark.
+"""
+
+from __future__ import division
+
+from twisted.internet.defer import Deferred
+from twisted.internet.protocol import ServerFactory, ClientCreator, Protocol
+from twisted.protocols.wire import Echo
+
+from benchlib import driver
+
+
+class Counter(Protocol):
+ count = 0
+
+ def dataReceived(self, bytes):
+ self.count += len(bytes)
+
+
+
+class Client(object):
+ _finished = None
+
+ def __init__(self, reactor, port):
+ self._reactor = reactor
+ self._port = port
+
+
+ def run(self, duration, chunkSize):
+ self._duration = duration
+ self._bytes = 'x' * chunkSize
+ # Set up a connection
+ cc = ClientCreator(self._reactor, Counter)
+ d = cc.connectTCP('127.0.0.1', self._port)
+ d.addCallback(self._connected)
+ return d
+
+
+ def _connected(self, client):
+ self._client = client
+ self._stopCall = self._reactor.callLater(self._duration, self._stop)
+ client.transport.registerProducer(self, False)
+ self._finished = Deferred()
+ return self._finished
+
+
+ def _stop(self):
+ self.stopProducing()
+ self._client.transport.unregisterProducer()
+ self._finish(self._client.count)
+
+
+ def _finish(self, value):
+ if self._finished is not None:
+ finished = self._finished
+ self._finished = None
+ finished.callback(value)
+
+
+ def resumeProducing(self):
+ self._client.transport.write(self._bytes)
+
+
+ def stopProducing(self):
+ self._client.transport.loseConnection()
+
+
+ def connectionLost(self, reason):
+ self._finish(reason)
+
+
+
+def main(reactor, duration):
+ chunkSize = 16384
+
+ server = ServerFactory()
+ server.protocol = Echo
+ serverPort = reactor.listenTCP(0, server)
+ client = Client(reactor, serverPort.getHost().port)
+ d = client.run(duration, chunkSize)
+ return d
+
+
+if __name__ == '__main__':
+ import sys
+ import tcp
+ driver(tcp.main, sys.argv)
Added: pypy/benchmarks/own/twisted/threads.py
==============================================================================
--- (empty file)
+++ pypy/benchmarks/own/twisted/threads.py Fri Mar 5 17:20:22 2010
@@ -0,0 +1,29 @@
+
+from __future__ import division
+
+from twisted.internet.threads import deferToThread
+
+from benchlib import Client, driver
+
+
+class Client(Client):
+ def _request(self):
+ d = deferToThread(lambda: None)
+ d.addCallback(self._continue)
+ d.addErrback(self._stop)
+
+
+
+def main(reactor, duration):
+ concurrency = 10
+
+ client = Client(reactor)
+ d = client.run(concurrency, duration)
+ return d
+
+
+
+if __name__ == '__main__':
+ import sys
+ import threads
+ driver(threads.main, sys.argv)
Added: pypy/benchmarks/own/twisted/web.py
==============================================================================
--- (empty file)
+++ pypy/benchmarks/own/twisted/web.py Fri Mar 5 17:20:22 2010
@@ -0,0 +1,76 @@
+
+"""
+This benchmark runs a trivial Twisted Web server and client and makes as
+many requests as it can in a fixed period of time.
+
+A significant problem with this benchmark is the lack of persistent
+connections in the HTTP client. Lots of TCP connections means lots of
+overhead in the kernel that's not really what we're trying to benchmark.
+Plus lots of sockets end up in TIME_WAIT which has a (briefly) persistent
+effect on system-wide performance and makes consecutive runs of the
+benchmark vary wildly in their results.
+"""
+
+from __future__ import division
+
+from twisted.internet.protocol import Protocol
+from twisted.internet.defer import Deferred
+from twisted.web.server import Site
+from twisted.web.static import Data
+from twisted.web.resource import Resource
+from twisted.web.client import ResponseDone, Agent
+
+from benchlib import Client, driver
+
+
+class BodyConsumer(Protocol):
+ def __init__(self, finished):
+ self.finished = finished
+
+ def connectionLost(self, reason):
+ if reason.check(ResponseDone):
+ self.finished.callback(None)
+ else:
+ self.finished.errback(reason)
+
+
+
+class Client(Client):
+ def __init__(self, reactor, portNumber, agent):
+ self._requestLocation = 'http://127.0.0.1:%d/' % (portNumber,)
+ self._agent = agent
+ super(Client, self).__init__(reactor)
+
+
+ def _request(self):
+ d = self._agent.request('GET', self._requestLocation)
+ d.addCallback(self._read)
+ d.addCallback(self._continue)
+ d.addErrback(self._stop)
+
+
+ def _read(self, response):
+ finished = Deferred()
+ response.deliverBody(BodyConsumer(finished))
+ return finished
+
+
+
+def main(reactor, duration):
+ concurrency = 10
+
+ root = Resource()
+ root.putChild('', Data("Hello, world", "text/plain"))
+ port = reactor.listenTCP(
+ 0, Site(root), backlog=128, interface='127.0.0.1')
+ agent = Agent(reactor)
+ client = Client(reactor, port.getHost().port, agent)
+ d = client.run(concurrency, duration)
+ return d
+
+
+
+if __name__ == '__main__':
+ import sys
+ import web
+ driver(web.main, sys.argv)
Modified: pypy/benchmarks/unladen_swallow/perf.py
==============================================================================
--- pypy/benchmarks/unladen_swallow/perf.py (original)
+++ pypy/benchmarks/unladen_swallow/perf.py Fri Mar 5 17:20:22 2010
@@ -754,7 +754,7 @@
def MeasureGeneric(python, options, bm_path, bm_env=None,
- extra_args=[], iteration_scaling=1):
+ extra_args=[], iteration_scaling=1, parser=float):
"""Abstract measurement function for Unladen's bm_* scripts.
Based on the values of options.fast/rigorous, will pass -n {5,50,100} to
@@ -792,7 +792,7 @@
result, mem_usage = CallAndCaptureOutput(command, bm_env,
track_memory=options.track_memory,
inherit_env=options.inherit_env)
- times = [float(line) for line in result.splitlines()]
+ times = [parser(line) for line in result.splitlines()]
return times, mem_usage
More information about the Pypy-commit
mailing list