Skip to content

Commit 99d4931

Browse files
committed
Add benchmarking tool
1 parent 78f5d0b commit 99d4931

File tree

4 files changed

+107
-0
lines changed

4 files changed

+107
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ ebin/*.beam
33
priv/*.so
44
c_src/*.o
55
deps
6+
graphs
67
perf/*.beam
78
.eunit
89
doc/edoc-info

Makefile

+7
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,10 @@ test: compile
3434

3535
docs:
3636
@./rebar doc
37+
38+
bench: perf
39+
@echo 'Running benchmarks, this could take some time...'
40+
@mkdir -p graphs
41+
@./perf/perfgraphs.py
42+
@mv -f *.png graphs/
43+

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ Run the test suite
4444

4545
$ make test
4646

47+
Run the benchmarks (requires [python](http://www.python.org) and [matplotlib](http://matplotlib.sourceforge.net/))
48+
49+
$ make bench
50+
51+
This will run performance tests and output png graphs in the graphs directory.
52+
4753
Please note that to behave properly on your system ZeroMQ might require [some tuning](http://www.zeromq.org/docs:tuning-zeromq).
4854

4955
Architecture

perf/perfgraphs.py

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#! /usr/bin/env python
2+
import subprocess
3+
import matplotlib.pyplot as plt
4+
5+
def do_test(localcmd, remotecmd):
6+
local = subprocess.Popen(localcmd.split(), stdout=subprocess.PIPE)
7+
remote = subprocess.Popen(remotecmd.split(), stdout=subprocess.PIPE,
8+
close_fds=True)
9+
local.wait()
10+
remote.wait()
11+
return (local.stdout.read(), remote.stdout.read())
12+
13+
def thr_run(iterations, msgsize=1, msgcount=100000, active=False):
14+
localcmd = "escript perf/local_thr"+(active and "_active" or "")+".erl" \
15+
" tcp://lo:1234 "+str(msgsize)+" "+str(msgcount)
16+
remotecmd = "escript perf/remote_thr.erl" \
17+
" tcp://localhost:1234 "+str(msgsize)+" "+str(msgcount)
18+
results = []
19+
for i in xrange(iterations):
20+
out = do_test(localcmd, remotecmd)[0]
21+
results.append(float(out.split('\n')[2].split(' ')[2]))
22+
return results
23+
24+
def lat_run(iterations, msgsize=1, msgcount=100000, active=False):
25+
localcmd = "escript perf/local_lat"+(active and "_active" or "")+".erl" \
26+
" tcp://lo:1234 "+str(msgsize)+" "+str(msgcount)
27+
remotecmd = "escript perf/remote_lat"+(active and "_active" or "")+".erl" \
28+
" tcp://localhost:1234 "+str(msgsize)+" "+str(msgcount)
29+
results = []
30+
for i in xrange(iterations):
31+
out = do_test(localcmd, remotecmd)[1]
32+
results.append(float(out.split('\n')[2].split(' ')[2]))
33+
return results
34+
35+
def average(l):
36+
return [sum(l)/float(len(l))]*len(l)
37+
38+
class TestRun(object):
39+
def __init__(self, iterations, msgsize, msgcount):
40+
self.iterations = iterations
41+
self.msgsize = msgsize
42+
self.msgcount = msgcount
43+
44+
def plot_all(self):
45+
self.plot_thr()
46+
self.plot_lat()
47+
48+
def title(self):
49+
return "%d messages in of %d byte(s)" % \
50+
(self.msgcount, self.msgsize)
51+
52+
def plot_thr(self):
53+
results = thr_run(self.iterations, self.msgsize,
54+
self.msgcount, False)
55+
results_active = thr_run(self.iterations, self.msgsize,
56+
self.msgcount, True)
57+
plt.clf()
58+
plt.title("Throughput: %s" % self.title())
59+
plt.ylabel("Msg/s")
60+
plt.plot(results, 'bo-', label="passive")
61+
plt.plot(average(results), 'b-', label="passive average",
62+
linewidth=2)
63+
plt.plot(results_active, 'ro-', label="active")
64+
plt.plot(average(results_active), 'r-', label="active average",
65+
linewidth=2)
66+
plt.legend()
67+
plt.savefig("thr_%d_%d_%d.png" % (self.iterations, self.msgsize,
68+
self.msgcount))
69+
70+
def plot_lat(self):
71+
results = lat_run(self.iterations, self.msgsize,
72+
self.msgcount, False)
73+
results_active = lat_run(self.iterations, self.msgsize,
74+
self.msgcount, True)
75+
plt.clf()
76+
plt.title("Latency: %s" % self.title())
77+
plt.ylabel("Average latency (us)")
78+
plt.plot(results, 'bo-', label="passive")
79+
plt.plot(average(results), 'b-', label="passive average",
80+
linewidth=2)
81+
plt.plot(results_active, 'ro-', label="active")
82+
plt.plot(average(results_active), 'r-', label="active average",
83+
linewidth=2)
84+
plt.legend()
85+
plt.savefig("lat_%d_%d_%d.png" % (self.iterations, self.msgsize,
86+
self.msgcount))
87+
88+
if __name__ == "__main__":
89+
TestRun(100, 1, 100000).plot_thr()
90+
TestRun(50, 1024, 100000).plot_thr()
91+
TestRun(40, 1, 10000).plot_lat()
92+
TestRun(20, 1024, 10000).plot_lat()
93+

0 commit comments

Comments
 (0)