Some profiling results

I've made a small test to see how my experimental Rete implementation is performing. I'm using a very simple rule that generates a lot of tokens:

>>> @pyRete.Rule
... def rule(a = Foo, b = Foo):
... if a.n > 10 and b.n < 20 and a.n > b.n:
... print a.n, b.n
where Foo is a value object.

I'm comparing against the pyRete version currently in Subversion and the results are not looking good. In fact, they're looking *so* bad, I believe it is because of an error in the pyRete implementation rather than a difference in time for object+ method lookups (which is what I hoped to test).

I'm only timing the assert_fact method calls (and the index loop):
... start = time.time()
... for i in range(size):
... pyRete.assert_fact(Foo(n=i))
... stop = time.time()
so Rete compilation, parsing and such is not included. Here are the results:

using 50 facts [Foo(0), Foo(1), ..., Foo(49)]
rule: +O+O+A+A+B+P
pyRete implementation took 0.210000038147 s => 735 facts
expRete implementation took 0.0599999427795 s => 735 facts

using 100 facts [Foo(0), Foo(1), ..., Foo(99)]
rule: +O+O+A+A+B+P
pyRete implementation took 0.871000051498 s => 1735 facts
expRete implementation took 0.149999856949 s => 1735 facts

using 200 facts [Foo(0), Foo(1), ..., Foo(199)]
rule: +O+O+A+A+B+P
pyRete implementation took 3.51600003242 s => 3735 facts
expRete implementation took 0.319999933243 s => 3735 facts

using 300 facts [Foo(0), Foo(1), ..., Foo(299)]
rule: +O+O+A+A+B+P
pyRete implementation took 7.84099984169 s => 5735 facts
expRete implementation took 0.481000185013 s => 5735 facts

using 400 facts [Foo(0), Foo(1), ..., Foo(399)]
rule: +O+O+A+A+B+P
pyRete implementation took 14.0199999809 s => 7735 facts
expRete implementation took 0.671000003815 s => 7735 facts

Clearly, something's not right. Going from 300 to 400 fact objects shouldn't take nearly twice as long.

Now, in order to be fair I should also mention that the experimental Rete implementation is hand-made (but it's topology is identical to that pyRete generates) and doesn't include things like callbacks for debugging, compilation, activations and statistics. However, that cannot account for *all* of the extra time, maybe some of it. I don't know.

I will try to make a hand-made, slimmed OO Rete Network tomorrow to see if I can get a fair comparison.

2 kommentarer:

woolfel sa...

I'm sure you'll figure out the problem. microbenchmarks are very useful for figuring out potential design and implementation bugs :)

atleast it was for me.

Johan Lindberg sa...

Hi Peter,

well, what irritates me is that I ran a couple of similar tests a while ago and the Rete implementation that I had then didn't behave like this so I was very suprised when I saw the result. I have apparently at some point introduced some code that completely breaks the Rete network.

I really need to start using a test framework for pyRete.