More benchmarks
This commit is contained in:
1 parent
e67009862f
commit
9323023262
7 files changed
+211
-38
No files matched your search
+140
-31
@@ -1,56 +1,165 @@
|
||||
|
||||
import sys
|
||||
import os
|
||||
from xml.dom.minidom import getDOMImplementation
|
||||
from timeit import Timer
|
||||
import subprocess
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
'..', 'build', 'default', 'benchmarks'))
|
||||
|
||||
from timeit import Timer
|
||||
|
||||
TIMES = 10000000
|
||||
TIMES1 = TIMES/4
|
||||
|
||||
import testapi_pybindgen
|
||||
import testapi_boost
|
||||
import testapi_swig
|
||||
|
||||
|
||||
|
||||
def bench(mod):
|
||||
def bench3():
|
||||
return mod.Multiplier()
|
||||
print "test3 (call class constructor with no arguments):", Timer(bench3).timeit(TIMES)
|
||||
|
||||
def bench4():
|
||||
return mod.Multiplier(3.0)
|
||||
print "test4 (call class constructor with double):", Timer(bench4).timeit(TIMES)
|
||||
|
||||
obj = mod.Multiplier(3.0)
|
||||
def bench5():
|
||||
return obj.GetFactor()
|
||||
print "test4 (call method with no arguments):", Timer(bench5).timeit(TIMES)
|
||||
|
||||
obj = mod.Multiplier(3.0)
|
||||
def bench6():
|
||||
return obj.Multiply(5.0)
|
||||
print "test4 (call method with double):", Timer(bench6).timeit(TIMES)
|
||||
|
||||
def bench1():
|
||||
def bench(mod, dom, elem):
|
||||
def bench():
|
||||
return mod.func1()
|
||||
print "test1 (call function with no arguments):", Timer(bench1).timeit(TIMES)
|
||||
tst = elem.appendChild(dom.createElement('test'))
|
||||
tst.setAttribute("description", "call function with no arguments")
|
||||
tst.setAttribute("time", repr(Timer(bench).timeit(TIMES)))
|
||||
print "%s (%s): %s" % (tst.tagName, tst.getAttribute('description'), tst.getAttribute('time'))
|
||||
|
||||
def bench2():
|
||||
def bench():
|
||||
return mod.func2(1.0, 2.0, 3.0)
|
||||
print "test2 (call function taking 3 doubles):", Timer(bench2).timeit(TIMES)
|
||||
tst = elem.appendChild(dom.createElement('test'))
|
||||
tst.setAttribute("description", "call function taking 3 doubles")
|
||||
tst.setAttribute("time", repr(Timer(bench).timeit(TIMES)))
|
||||
print "%s (%s): %s" % (tst.tagName, tst.getAttribute('description'), tst.getAttribute('time'))
|
||||
|
||||
def bench():
|
||||
return mod.Multiplier()
|
||||
tst = elem.appendChild(dom.createElement('test'))
|
||||
tst.setAttribute("description", "call class constructor with no arguments")
|
||||
tst.setAttribute("time", repr(Timer(bench).timeit(TIMES)))
|
||||
print "%s (%s): %s" % (tst.tagName, tst.getAttribute('description'), tst.getAttribute('time'))
|
||||
|
||||
def bench():
|
||||
return mod.Multiplier(3.0)
|
||||
tst = elem.appendChild(dom.createElement('test'))
|
||||
tst.setAttribute("description", "call class constructor with double")
|
||||
tst.setAttribute("time", repr(Timer(bench).timeit(TIMES)))
|
||||
print "%s (%s): %s" % (tst.tagName, tst.getAttribute('description'), tst.getAttribute('time'))
|
||||
|
||||
obj = mod.Multiplier(3.0)
|
||||
def bench():
|
||||
return obj.GetFactor()
|
||||
tst = elem.appendChild(dom.createElement('test'))
|
||||
tst.setAttribute("description", "call simple method")
|
||||
tst.setAttribute("time", repr(Timer(bench).timeit(TIMES)))
|
||||
print "%s (%s): %s" % (tst.tagName, tst.getAttribute('description'), tst.getAttribute('time'))
|
||||
|
||||
obj = mod.Multiplier(3.0)
|
||||
def bench():
|
||||
return obj.SetFactor()
|
||||
tst = elem.appendChild(dom.createElement('test'))
|
||||
tst.setAttribute("description", "call overloaded method 1")
|
||||
tst.setAttribute("time", repr(Timer(bench).timeit(TIMES)))
|
||||
print "%s (%s): %s" % (tst.tagName, tst.getAttribute('description'), tst.getAttribute('time'))
|
||||
|
||||
obj = mod.Multiplier(3.0)
|
||||
def bench():
|
||||
return obj.SetFactor(1.0)
|
||||
tst = elem.appendChild(dom.createElement('test'))
|
||||
tst.setAttribute("description", "call overloaded method 2")
|
||||
tst.setAttribute("time", repr(Timer(bench).timeit(TIMES)))
|
||||
print "%s (%s): %s" % (tst.tagName, tst.getAttribute('description'), tst.getAttribute('time'))
|
||||
|
||||
obj = mod.Multiplier(3.0)
|
||||
def bench():
|
||||
return obj.Multiply(5.0)
|
||||
tst = elem.appendChild(dom.createElement('test'))
|
||||
tst.setAttribute("description", "call non-overridden virtual method with double")
|
||||
tst.setAttribute("time", repr(Timer(bench).timeit(TIMES)))
|
||||
print "%s (%s): %s" % (tst.tagName, tst.getAttribute('description'), tst.getAttribute('time'))
|
||||
|
||||
if mod is testapi_pybindgen:
|
||||
class M(mod.Multiplier):
|
||||
def _Multiply(self, value):
|
||||
#print "Multiply", value, " return ", super(M, self)._Multiply(value)
|
||||
return super(M, self)._Multiply(value)
|
||||
elif mod is testapi_boost:
|
||||
class M(mod.Multiplier):
|
||||
def Multiply(self, value):
|
||||
#print "Multiply", value, " return ", super(M, self).Multiply(value)
|
||||
return super(M, self).Multiply(value)
|
||||
elif mod is testapi_swig:
|
||||
class M(mod.Multiplier):
|
||||
def Multiply(self, value):
|
||||
#print "Multiply", value, " return ", super(M, self).Multiply(value)
|
||||
return super(M, self).Multiply(value)
|
||||
else:
|
||||
raise NotImplementedError
|
||||
obj = M(2.0)
|
||||
def bench():
|
||||
return obj.Multiply(5.0)
|
||||
|
||||
tst = elem.appendChild(dom.createElement('test'))
|
||||
tst.setAttribute("description", "call python-overridden virtual method from Python")
|
||||
tst.setAttribute("time", repr(Timer(bench).timeit(TIMES1)))
|
||||
print "%s (%s): %s" % (tst.tagName, tst.getAttribute('description'), tst.getAttribute('time'))
|
||||
|
||||
def bench():
|
||||
return mod.call_virtual_from_cpp(obj, 5.0)
|
||||
tst = elem.appendChild(dom.createElement('test'))
|
||||
tst.setAttribute("description", "call python-overridden virtual method from C++")
|
||||
tst.setAttribute("time", repr(Timer(bench).timeit(TIMES1)))
|
||||
print "%s (%s): %s" % (tst.tagName, tst.getAttribute('description'), tst.getAttribute('time'))
|
||||
|
||||
|
||||
def main():
|
||||
import testapi_pybindgen
|
||||
import testapi_boost
|
||||
import testapi_swig
|
||||
impl = getDOMImplementation()
|
||||
dom = impl.createDocument(None, "pybindgen-benchmarks", None)
|
||||
top = dom.documentElement
|
||||
|
||||
env = top.appendChild(dom.createElement('environment'))
|
||||
env.appendChild(dom.createElement('compiler')).appendChild(dom.createTextNode(
|
||||
subprocess.Popen(["g++", "-v"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0]))
|
||||
env.appendChild(dom.createElement('python')).appendChild(dom.createTextNode(
|
||||
sys.version))
|
||||
env.appendChild(dom.createElement('swig')).appendChild(dom.createTextNode(
|
||||
subprocess.Popen(["swig", "-version"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0]))
|
||||
env.appendChild(dom.createElement('boost_python')).appendChild(dom.createTextNode(
|
||||
subprocess.Popen(["dpkg", "-s", "libboost-python-dev"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0]))
|
||||
env.appendChild(dom.createElement('pybindgen')).appendChild(dom.createTextNode(
|
||||
subprocess.Popen(["bzr", "revno"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0]))
|
||||
|
||||
env.appendChild(dom.createElement('cpu')).appendChild(dom.createTextNode(
|
||||
file("/proc/cpuinfo").read()))
|
||||
|
||||
if len(sys.argv) == 3:
|
||||
env.appendChild(dom.createElement('CXXFLAGS')).appendChild(dom.createTextNode(sys.argv[2]))
|
||||
|
||||
|
||||
res = top.appendChild(dom.createElement('results'))
|
||||
|
||||
|
||||
print "pybindgen results:"
|
||||
bench(testapi_pybindgen)
|
||||
pbg = res.appendChild(dom.createElement('pybindgen'))
|
||||
pbg.setAttribute("module-file-size", repr(os.stat("build/default/benchmarks/testapi_pybindgen.so").st_size))
|
||||
bench(testapi_pybindgen, dom, pbg)
|
||||
|
||||
print "boost_python results:"
|
||||
bench(testapi_boost)
|
||||
bp = res.appendChild(dom.createElement('boost_python'))
|
||||
bp.setAttribute("module-file-size", repr(os.stat("build/default/benchmarks/testapi_boost.so").st_size))
|
||||
bench(testapi_boost, dom, bp)
|
||||
|
||||
print "swig results:"
|
||||
bench(testapi_swig)
|
||||
sw = res.appendChild(dom.createElement('swig'))
|
||||
sw.setAttribute("module-file-size", repr(os.stat("build/default/benchmarks/_testapi_swig.so").st_size))
|
||||
sw.setAttribute("module-python-file-size", repr(os.stat("build/default/benchmarks/testapi_swig.py").st_size))
|
||||
bench(testapi_swig, dom, sw)
|
||||
|
||||
if len(sys.argv) == 3:
|
||||
f = open(sys.argv[1], "wb")
|
||||
dom.writexml(f, "", " ", "\n")
|
||||
f.close()
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -21,7 +21,11 @@ def my_module_gen(out_file):
|
||||
Multiplier.add_constructor([param('double', 'factor')])
|
||||
|
||||
Multiplier.add_method('GetFactor', 'double', [], is_const=True)
|
||||
Multiplier.add_method('SetFactor', 'void', [param('double', 'f')], is_const=True)
|
||||
Multiplier.add_method('SetFactor', 'void', [], is_const=True)
|
||||
Multiplier.add_method('Multiply', 'double', [param('double', 'value')], is_virtual=True, is_const=True)
|
||||
|
||||
mod.add_function('call_virtual_from_cpp', 'double', [param('Multiplier const *', 'obj'), param('double', 'value')])
|
||||
|
||||
|
||||
mod.generate(FileCodeSink(out_file))
|
||||
|
||||
@@ -21,12 +21,25 @@ Multiplier::Multiplier (double factor)
|
||||
{
|
||||
}
|
||||
|
||||
Multiplier::~Multiplier ()
|
||||
{
|
||||
}
|
||||
|
||||
double Multiplier::GetFactor () const
|
||||
{
|
||||
return m_factor;
|
||||
}
|
||||
|
||||
void Multiplier::SetFactor (double f)
|
||||
{
|
||||
m_factor = f;
|
||||
}
|
||||
|
||||
void Multiplier::SetFactor ()
|
||||
{
|
||||
m_factor = 1.0;
|
||||
}
|
||||
|
||||
double
|
||||
Multiplier::Multiply (double value) const
|
||||
{
|
||||
@@ -34,3 +47,9 @@ Multiplier::Multiply (double value) const
|
||||
}
|
||||
|
||||
|
||||
double
|
||||
call_virtual_from_cpp (Multiplier const *obj, double value)
|
||||
{
|
||||
return obj->Multiply (value);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ void func1 (void);
|
||||
|
||||
double func2 (double x, double y, double z);
|
||||
|
||||
|
||||
class Multiplier
|
||||
{
|
||||
double m_factor;
|
||||
@@ -14,10 +15,14 @@ class Multiplier
|
||||
public:
|
||||
Multiplier ();
|
||||
Multiplier (double factor);
|
||||
virtual ~Multiplier ();
|
||||
|
||||
void SetFactor (double f);
|
||||
void SetFactor (void);
|
||||
double GetFactor () const;
|
||||
virtual double Multiply (double value) const;
|
||||
};
|
||||
|
||||
double call_virtual_from_cpp (Multiplier const *obj, double value);
|
||||
|
||||
#endif
|
||||
@@ -3,16 +3,44 @@
|
||||
|
||||
#include <boost/python.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
void (Multiplier::*factor1) () = &Multiplier::SetFactor;
|
||||
void (Multiplier::*factor2) (double) = &Multiplier::SetFactor;
|
||||
|
||||
struct MultiplierWrap : Multiplier, wrapper<Multiplier>
|
||||
{
|
||||
MultiplierWrap () : Multiplier ()
|
||||
{
|
||||
}
|
||||
MultiplierWrap (double factor) : Multiplier (factor)
|
||||
{
|
||||
}
|
||||
|
||||
double Multiply (double value) const
|
||||
{
|
||||
return this->get_override("Multiply") (value);
|
||||
}
|
||||
|
||||
double default_Multiply (double value) const
|
||||
{
|
||||
return this->Multiplier::Multiply (value);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(testapi_boost)
|
||||
{
|
||||
using namespace boost::python;
|
||||
def("func1", func1);
|
||||
def("func2", func2);
|
||||
def("call_virtual_from_cpp", call_virtual_from_cpp);
|
||||
|
||||
class_<Multiplier>("Multiplier")
|
||||
class_<MultiplierWrap, boost::noncopyable>("Multiplier")
|
||||
.def(init<double>())
|
||||
.def("GetFactor", &Multiplier::GetFactor)
|
||||
.def("Multiply", &Multiplier::Multiply)
|
||||
.def("GetFactor", &Multiplier::GetFactor)
|
||||
.def("SetFactor", factor1)
|
||||
.def("SetFactor", factor2)
|
||||
.def("Multiply", &Multiplier::Multiply, &MultiplierWrap::default_Multiply)
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/* example.i */
|
||||
|
||||
%module testapi_swig
|
||||
%module(directors="1") testapi_swig
|
||||
%feature("director");
|
||||
|
||||
%{
|
||||
|
||||
#include "testapi.h"
|
||||
@@ -16,8 +18,13 @@ class Multiplier
|
||||
|
||||
public:
|
||||
Multiplier ();
|
||||
virtual ~Multiplier ();
|
||||
Multiplier (double factor);
|
||||
|
||||
void SetFactor (double f);
|
||||
void SetFactor (void);
|
||||
double GetFactor () const;
|
||||
virtual double Multiply (double value) const;
|
||||
};
|
||||
|
||||
extern double call_virtual_from_cpp (Multiplier const *obj, double value);
|
||||
|
||||
@@ -309,7 +309,8 @@ def bench(bld):
|
||||
env = g_bld.env
|
||||
|
||||
print "Running benchmarks..."
|
||||
retval = subprocess.Popen([env['PYTHON'], '-O', 'benchmarks/bench.py']).wait()
|
||||
retval = subprocess.Popen([env['PYTHON'], '-O', 'benchmarks/bench.py',
|
||||
"build/default/benchmarks/results.xml", ' '.join(env['CXXFLAGS_PYEXT'] + env['CXXFLAGS'])]).wait()
|
||||
|
||||
|
||||
check_context = Build.BuildContext
|
||||
|
||||
Reference in new issue
Block a user