Peter Lin published a set of simple Jess/Clips tests designed to show scalability characteristics in various scenarios. These can be downloaded from http://dingo.sourceforge.net/rete-benchmark.zip. I undertook to replicate these tests in the Microsoft Business Rules Engine for comparison, and to publish the results. There were five tests in all. However, one of these tests (Ordered Facts) was not repeatable in MS-BRE. In contrast to Jess and Clips, MS-BRE does not employ a LISP-like approach, and has no equivalent concept of ordered facts. Rather, facts are always asserted as .NET objects (using specialised classes as required to bind to XML documents or ADO.NET datasets), and facts in MS-BRE are therefore somewhat similar to the Jess/Clips concept of unordered facts.
I encountered two difficulties while replicating the tests. The first is that some of the rules files provided by Peter for the Mixed-Set test appear it be incorrect. Rule files rules5k-mix.clp to rules10k-mix.clp, inclusive, appear to use the ‘object1’ fact in every rule, whereas they should, I believe, be using the ‘object2’ fact for rules 1000 and greater. I ran the provided rules through Jess, and got very different results to Peter. I then amended the rules to what I believe they should be, and re-ran the tests. This time I got similar results to Peter’s. I have therefore used the amended rules here.
The second problem concerns the Unique-Object test. The rule files provided by Peter appear to be correct, but every time I run this through Jess on my local machine, I get significantly different results to Peter’s. This is shown in the graph below:

I wondered if perhaps the original test had been conducted with varying numbers of facts. However, Peter’s results indicate that exactly 1000 rules fired for each rule set size, which implies that the same 1000 facts were submitted for each run. Certainly I would expect the Rete algorithm to provide results similar to the one I obtained, rather than those provided by Peter. For the purposes of this comparison, I have used the rules and data provided by Peter, but have compared the MS-BRE results to those obtained using Jess on my machine.
I have provided further details of how I translated the rules in MS-BRL in Appendix A I have provided the full results in Appendix B. The results are summarised below. Please note that, again in order to avoid unhelpful comparison or raw performance, I have adjusted the ‘y’ axis for the first two tests (1K-Facts and 1K Facts Fire Each) so that a direct comparison of scaling characteristics can more easily be made. For other tests, I have shown the graphs using actual times.
Results
1K Facts

1K Facts Fire Each

Unique Object
(NB. Jess times are mine, rather than Peter’s – see above)

Mixed Set

Conclusions
The results suggest that, within the limitations of the tests published by Peter, the Microsoft Business Rules Engine exhibits similar scaling characteristics to Jess. This, in turn, may provide some evidence to support the claim that Microsoft’s engine implements the Rete algorithm correctly.
Appendix A
Rule Translation
In order to conduct the tests, it was necessary to translate the Jess/CLIPS rules into equivalent Microsoft Business Rule Language. This appendix provides indicates the form of the MS-BRL rules. The same form was used across all rules, although the names of rules and ‘object’ facts varied, as did the value of the attr1 slot.
Examples of the rules are shown below:
Jess
(defrule rule0
(object1
(attr1 "0")
=>
(printout t "rule0 fired")
)
<rule name="rule0" priority="0" active="true">
<if>
<compare operator="equal">
<lhs>
<function>
<classmember classref="object1"
member="get_Attr1"
sideeffects="false" />
</function>
</lhs>
<rhs>
<constant>
<string>0</string>
</constant>
</rhs>
</compare>
</if>
<then>
<function>
<classmember classref="object1"
member="PrintOut"
sideeffects="true">
<argument>
<constant>
<string>rule0fired</string>
</constant>
</argument>
</classmember>
</function>
</then>
</rule>
N.B., The MS-BRL rule is more closely equivalent to the following Jess rule:
(defrule rule0
(object1
(attr1 ?x&:(eq ?x "0")))
=>
(printout t "rule0 fired")
)
MS-BRE does not implement a LISP-like approach, and has no equivalent to Jess’ ability to look up facts in the knowledge base. Note that the Jess rule used by Peter is significantly more efficient that the alternative shown here.
Appendix B
Detailed Results
As I have done elsewhere, I must emphasise that the purpose of these tests was to investigate the scalability characteristics of the three engines in relation to Microsoft's original test results for MS-BRE, and not to provide evidence of performance in terms of speed. All times in ms.
1K Facts
|
1000 |
2000 |
3000 |
4000 |
5000 |
6000 |
7000 |
8000 |
9000 |
10000 |
|
|
|
|
|
|
|
|
|
|
|
|
761 |
1672 |
2804 |
3094 |
4046 |
4717 |
5828 |
6920 |
6910 |
7581 |
|
821 |
1622 |
2544 |
3185 |
4206 |
5278 |
5989 |
7381 |
7711 |
7781 |
|
831 |
1602 |
2874 |
3615 |
4637 |
6019 |
6239 |
7250 |
7561 |
8022 |
|
851 |
1632 |
2784 |
3735 |
4557 |
5969 |
5728 |
7130 |
7791 |
8152 |
|
791 |
1692 |
2784 |
3775 |
4376 |
5298 |
6610 |
6860 |
8022 |
8222 |
|
Averages |
|
|
|
|
|
|
|
|
|
|
811 |
1644 |
2758 |
3480.8 |
4364.4 |
5456.2 |
6078.8 |
7108.2 |
7599 |
7951.6 |
1K Facts Fire Each
|
1000 |
2000 |
3000 |
4000 |
5000 |
6000 |
7000 |
8000 |
9000 |
10000 |
|
|
|
|
|
|
|
|
|
|
|
|
791 |
1712 |
2844 |
3385 |
4236 |
5127 |
5197 |
6089 |
6870 |
7671 |
|
791 |
1652 |
2534 |
3635 |
4466 |
5488 |
5598 |
6650 |
7631 |
8562 |
|
791 |
1732 |
2764 |
3705 |
4667 |
5628 |
6209 |
7210 |
7981 |
8703 |
|
791 |
1722 |
2754 |
3775 |
4667 |
5478 |
6209 |
7120 |
7901 |
8783 |
|
791 |
1753 |
2754 |
3695 |
4667 |
4887 |
5738 |
7100 |
7891 |
8793 |
|
Averages |
|
|
|
|
|
|
|
|
|
|
791 |
1714.2 |
2730 |
3639 |
4540.6 |
5321.6 |
5790.2 |
6833.8 |
7654.8 |
8502.4 |
Unique Object
|
1000 |
2000 |
3000 |
4000 |
5000 |
|
|
|
|
|
|
|
160 |
250 |
150 |
150 |
170 |
|
60 |
160 |
200 |
150 |
160 |
|
60 |
150 |
90 |
50 |
130 |
|
60 |
150 |
60 |
60 |
60 |
|
60 |
150 |
50 |
50 |
50 |
|
Averages |
|
|
|
|
|
80 |
172 |
110 |
92 |
114
|
Mixed Set
|
1000 |
2000 |
3000 |
4000 |
5000 |
6000 |
7000 |
8000 |
9000 |
10000 |
|
|
|
|
|
|
|
|
|
|
|
|
761 |
771 |
841 |
771 |
801 |
831 |
771 |
781 |
761 |
841 |
|
771 |
771 |
841 |
761 |
781 |
811 |
821 |
741 |
761 |
871 |
|
771 |
831 |
851 |
761 |
811 |
831 |
761 |
761 |
781 |
831 |
|
761 |
811 |
761 |
791 |
781 |
871 |
761 |
761 |
801 |
871 |
|
771 |
841 |
761 |
791 |
771 |
851 |
811 |
761 |
781 |
851 |
|
Averages |
|
|
|
|
|
|
|
|
|
|
767 |
805 |
811 |
775 |
789 |
839 |
785 |
761 |
777 |
853 |
All tests were conducted on the same machine. The specifications are provided below.
|
Property |
Value |
|
OS Name |
Microsoft Windows XP Professional |
|
Version |
5.1.2600 Service Pack 2 Build 2600 |
|
OS Manufacturer |
Microsoft Corporation |
|
System Manufacturer |
Clevo |
|
System Model |
4xx Series |
|
System Type |
X86-based PC |
|
Processor |
x86 Family 15 Model 2 Stepping 9 GenuineIntel ~2666 Mhz |
|
BIOS Version/Date |
Phoenix 4.06, 06/06/2003 |
|
SMBIOS Version |
2.3 |
|
Hardware Abstraction Layer |
Version = "5.1.2600.2180 (xpsp_sp2_rtm.040803-2158)" |
|
Total Physical Memory |
1,024.00 MB |
|
Available Physical Memory |
718.23 MB |
|
Total Virtual Memory |
2.00 GB |
|
Available Virtual Memory |
1.96 GB |
|
Page File Space |
2.40 GB |
The .NET code ran under .Net Framework 1.1.4322