Skip to content

Commit

Permalink
[DROOLS-7576] Add benchmarks for secondary super cache issue
Browse files Browse the repository at this point in the history
- ConcurrentUpdateRightTupleBenchmark calls RightTupleImpl.getTupleSink() a lot
- ConcurrentUpdateLeftTupleBenchmark calls LeftTuple.getTupleSink() a lot
  • Loading branch information
tkobayas committed Oct 24, 2023
1 parent 0ddde0a commit a5fb68c
Show file tree
Hide file tree
Showing 5 changed files with 318 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,14 @@ public A(final int value) {
public A(final long id, final int value) {
super(id, value);
}

private int value2;

public int getValue2() {
return value2;
}

public void setValue2(int value2) {
this.value2 = value2;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,14 @@ public B(final int value) {
public B(final long id, final int value) {
super(id, value);
}

private int value2;

public int getValue2() {
return value2;
}

public void setValue2(int value2) {
this.value2 = value2;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public class RulesWithJoinsProvider implements DRLProvider {
private String rootConstraintValueOperator = ">";
private String joinConstraintValueOperator = ">";

private boolean withNot = false;

public RulesWithJoinsProvider() { }

public RulesWithJoinsProvider(final int numberOfJoins, final boolean withCep, final boolean withImports ) {
Expand Down Expand Up @@ -96,6 +98,11 @@ public RulesWithJoinsProvider withGeneratedConsequence(boolean withGeneratedCons
return this;
}

public RulesWithJoinsProvider withNot(boolean withNot) {
this.withNot = withNot;
return this;
}

public RulesWithJoinsProvider withPrioritizedBySalience(boolean prioritizedBySalience) {
this.prioritizedBySalience = prioritizedBySalience;
return this;
Expand Down Expand Up @@ -170,7 +177,13 @@ private String getJoinConstraintsCep(int index) {
}

private String getJoinConstraints(int index) {
return " $" + (char)('b'+index) + " : " + (char)('B'+index) + "( value " + joinConstraintValueOperator + " $" + (char)('a'+index) + ".value )\n";
String pattern = " $" + (char)('b'+index) + " : " + (char)('B'+index) + "( value " + joinConstraintValueOperator + " $" + (char)('a'+index) + ".value )\n";
if (withNot) {
String notPattern = " not " + (char)('B'+index) + "( value < $" + (char)('a'+index) + ".value )\n";
return notPattern + pattern;
} else {
return pattern;
}
}

private String generateConsequence() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* Copyright 2023 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.drools.benchmarks.concurrent;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.drools.benchmarks.common.AbstractBenchmark;
import org.drools.benchmarks.common.model.A;
import org.drools.benchmarks.common.model.B;
import org.drools.benchmarks.common.model.C;
import org.drools.benchmarks.common.model.D;
import org.drools.benchmarks.common.providers.RulesWithJoinsProvider;
import org.drools.benchmarks.common.util.BuildtimeUtil;
import org.drools.benchmarks.common.util.RuntimeUtil;
import org.drools.kiesession.session.StatefulKnowledgeSessionImpl;
import org.kie.api.conf.EventProcessingOption;
import org.kie.api.runtime.KieSession;
import org.kie.internal.conf.ParallelExecutionOption;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.TearDown;
import org.openjdk.jmh.annotations.Warmup;

@Warmup(iterations = 20)
@Measurement(iterations = 20)
public class ConcurrentUpdateLeftTupleBenchmark extends AbstractBenchmark {

@Param({"32"})
private int rulesNr;

@Param({"15"})
private int factsNr;

@Param({"3"})
private int joinsNr;

private static final int SESSIONS_NR = 20;

private List<KieSession> kieSessions = new ArrayList<>(); // Do not use kieSession in AbstractBenchmark

@Setup
public void setupKieBase() {
final RulesWithJoinsProvider drlProvider = new RulesWithJoinsProvider(joinsNr, false, true)
.withNot(true)
.withGeneratedConsequence(false)
.withConsequence(" $a.setValue2($a.getValue2() + 1);\n" +
" update($a);\n");
//System.out.println(drlProvider.getDrl(rulesNr));
kieBase = BuildtimeUtil.createKieBaseFromDrl(drlProvider.getDrl(rulesNr),
ParallelExecutionOption.SEQUENTIAL,
EventProcessingOption.CLOUD);
//ReteDumper.dumpRete(kieBase);
}

@Setup(Level.Iteration)
@Override
public void setup() {
for (int n = 0; n < SESSIONS_NR; n++) {
StatefulKnowledgeSessionImpl session = (StatefulKnowledgeSessionImpl) RuntimeUtil.createKieSession(kieBase);
A a = new A(rulesNr + 1);

session.insert(a);

for (int i = 0; i < factsNr; i++) {

session.insert(new B(rulesNr + i + 3));
if (joinsNr > 1) {
session.insert(new C(rulesNr + factsNr + i + 3));
}
if (joinsNr > 2) {
session.insert(new D(rulesNr + factsNr * 2 + i + 3));
}
}
kieSessions.add(session);
}
}

@TearDown(Level.Iteration)
public void tearDoneIter() {
for (int n = 0; n < SESSIONS_NR; n++) {
kieSessions.get(n).dispose();
}
kieSessions.clear();
}

@Benchmark
public int test() {
ExecutorService executor = Executors.newFixedThreadPool(SESSIONS_NR);

for (int n = 0; n < SESSIONS_NR; n++) {
final int index = n;
executor.execute(new Runnable() {

public void run() {
int fired = kieSessions.get(index).fireAllRules();
// System.out.println(fired);
}
});
}

executor.shutdown();
try {
executor.awaitTermination(300, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return kieSessions.size();
}

public static void main(String[] args) {
ConcurrentUpdateLeftTupleBenchmark benchmark = new ConcurrentUpdateLeftTupleBenchmark();

benchmark.rulesNr = 32;
benchmark.factsNr = 15;
benchmark.joinsNr = 3;

benchmark.setupKieBase();
benchmark.setup();
benchmark.test();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* Copyright 2023 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.drools.benchmarks.concurrent;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.drools.benchmarks.common.AbstractBenchmark;
import org.drools.benchmarks.common.model.A;
import org.drools.benchmarks.common.model.B;
import org.drools.benchmarks.common.model.C;
import org.drools.benchmarks.common.model.D;
import org.drools.benchmarks.common.providers.RulesWithJoinsProvider;
import org.drools.benchmarks.common.util.BuildtimeUtil;
import org.drools.benchmarks.common.util.RuntimeUtil;
import org.drools.kiesession.session.StatefulKnowledgeSessionImpl;
import org.kie.api.conf.EventProcessingOption;
import org.kie.api.runtime.KieSession;
import org.kie.internal.conf.ParallelExecutionOption;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.TearDown;
import org.openjdk.jmh.annotations.Warmup;

@Warmup(iterations = 20)
@Measurement(iterations = 20)
public class ConcurrentUpdateRightTupleBenchmark extends AbstractBenchmark {

@Param({"32"})
private int rulesNr;

@Param({"15"})
private int factsNr;

@Param({"3"})
private int joinsNr;

private static final int SESSIONS_NR = 20;

private List<KieSession> kieSessions = new ArrayList<>(); // Do not use kieSession in AbstractBenchmark

@Setup
public void setupKieBase() {
final RulesWithJoinsProvider drlProvider = new RulesWithJoinsProvider(joinsNr, false, true)
.withNot(true)
.withGeneratedConsequence(false)
.withConsequence(" $b.setValue2($b.getValue2() + 1);\n" +
" update($b);\n");
//System.out.println(drlProvider.getDrl(rulesNr));
kieBase = BuildtimeUtil.createKieBaseFromDrl(drlProvider.getDrl(rulesNr),
ParallelExecutionOption.SEQUENTIAL,
EventProcessingOption.CLOUD);
//ReteDumper.dumpRete(kieBase);
}

@Setup(Level.Iteration)
@Override
public void setup() {
for (int n = 0; n < SESSIONS_NR; n++) {
StatefulKnowledgeSessionImpl session = (StatefulKnowledgeSessionImpl) RuntimeUtil.createKieSession(kieBase);
A a = new A(rulesNr + 1);

session.insert(a);

for (int i = 0; i < factsNr; i++) {

session.insert(new B(rulesNr + i + 3));
if (joinsNr > 1) {
session.insert(new C(rulesNr + factsNr + i + 3));
}
if (joinsNr > 2) {
session.insert(new D(rulesNr + factsNr * 2 + i + 3));
}
}
kieSessions.add(session);
}
}

@TearDown(Level.Iteration)
public void tearDoneIter() {
for (int n = 0; n < SESSIONS_NR; n++) {
kieSessions.get(n).dispose();
}
kieSessions.clear();
}

@Benchmark
public int test() {
ExecutorService executor = Executors.newFixedThreadPool(SESSIONS_NR);

for (int n = 0; n < SESSIONS_NR; n++) {
final int index = n;
executor.execute(new Runnable() {

public void run() {
int fired = kieSessions.get(index).fireAllRules();
// System.out.println(fired);
}
});
}

executor.shutdown();
try {
executor.awaitTermination(300, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return kieSessions.size();
}

public static void main(String[] args) {
ConcurrentUpdateRightTupleBenchmark benchmark = new ConcurrentUpdateRightTupleBenchmark();

benchmark.rulesNr = 32;
benchmark.factsNr = 15;
benchmark.joinsNr = 3;

benchmark.setupKieBase();
benchmark.setup();
benchmark.test();
}
}

0 comments on commit a5fb68c

Please sign in to comment.