diff --git a/drools-benchmarks-parent/drools-benchmarks/src/main/java/org/drools/benchmarks/dmn/codegen/AbstractCodegenBenchmark.java b/drools-benchmarks-parent/drools-benchmarks/src/main/java/org/drools/benchmarks/dmn/codegen/AbstractCodegenBenchmark.java new file mode 100644 index 00000000..02e2d39b --- /dev/null +++ b/drools-benchmarks-parent/drools-benchmarks/src/main/java/org/drools/benchmarks/dmn/codegen/AbstractCodegenBenchmark.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.dmn.codegen; + +import org.kie.dmn.api.core.DMNCompiler; +import org.kie.dmn.api.core.DMNCompilerConfiguration; +import org.kie.dmn.api.core.DMNContext; +import org.kie.dmn.api.core.DMNModel; +import org.kie.dmn.api.core.DMNRuntime; +import org.kie.dmn.core.compiler.DMNCompilerConfigurationImpl; +import org.kie.dmn.core.compiler.DMNCompilerImpl; +import org.kie.dmn.core.compiler.RuntimeTypeCheckOption; +import org.kie.dmn.core.impl.DMNRuntimeImpl; +import org.kie.dmn.core.internal.utils.DMNRuntimeBuilder; +import org.kie.dmn.feel.parser.feel11.profiles.DoCompileFEELProfile; +import org.kie.dmn.feel.util.Either; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.function.BiConsumer; +import java.util.function.Function; + +import static org.drools.benchmarks.dmn.util.DynamicTypeUtils.entry; +import static org.drools.benchmarks.dmn.util.DynamicTypeUtils.prototype; + +public abstract class AbstractCodegenBenchmark { + + private DMNRuntime dmnRuntime; + private DMNModel dmnModel; + private DMNContext dmnContext; + + protected abstract String getResource(); + protected abstract List getAdditionalResources(); + protected abstract String getNameSpace(); + protected abstract String getModelName(); + protected abstract Map getInputData(); + + protected void setupModelAndContext() { + Function dmnCompilerFn = dmnCompilerConfiguration -> { + ((DMNCompilerConfigurationImpl) dmnCompilerConfiguration).addFEELProfile(new DoCompileFEELProfile()); + return new DMNCompilerImpl(dmnCompilerConfiguration); + }; + DMNRuntimeBuilder.DMNRuntimeBuilderConfigured dmnRuntimeBuilderConfigured = DMNRuntimeBuilder.fromDefaults() + .buildConfigurationUsingCustomCompiler(dmnCompilerFn); + Either exceptionDMNRuntimeEither; + if (getAdditionalResources() != null && !getAdditionalResources().isEmpty()) { + exceptionDMNRuntimeEither = dmnRuntimeBuilderConfigured + .fromClasspathResources(getResource(), this.getClass(), getAdditionalResources().toArray(new String[0])); + } else { + exceptionDMNRuntimeEither = dmnRuntimeBuilderConfigured + .fromClasspathResource(getResource(), this.getClass()); + } + dmnRuntime = exceptionDMNRuntimeEither + .getOrElseThrow(e -> new RuntimeException("Error initializing DMNRuntime", e)); + ((DMNRuntimeImpl) dmnRuntime).setOption(new RuntimeTypeCheckOption(true)); + dmnModel = dmnRuntime.getModel( + getNameSpace(), + getModelName()); + if (dmnModel == null) { + throw new RuntimeException("Model " + getNameSpace() + "." + getModelName() + " not found"); + } + dmnContext = dmnRuntime.newContext(); + getInputData().forEach((key, value) -> dmnContext.set(key, value)); + } + + protected Object evaluateModelBenchmark() { + return dmnRuntime.evaluateAll(dmnModel, dmnContext); + } + + + +} diff --git a/drools-benchmarks-parent/drools-benchmarks/src/main/java/org/drools/benchmarks/dmn/codegen/ImportedModelCodegenBenchmark.java b/drools-benchmarks-parent/drools-benchmarks/src/main/java/org/drools/benchmarks/dmn/codegen/ImportedModelCodegenBenchmark.java new file mode 100644 index 00000000..27265fd9 --- /dev/null +++ b/drools-benchmarks-parent/drools-benchmarks/src/main/java/org/drools/benchmarks/dmn/codegen/ImportedModelCodegenBenchmark.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.dmn.codegen; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import static org.drools.benchmarks.dmn.util.DynamicTypeUtils.entry; +import static org.drools.benchmarks.dmn.util.DynamicTypeUtils.prototype; + +@BenchmarkMode(Mode.AverageTime) +@State(Scope.Thread) +@Warmup(iterations = 100, time = 200, timeUnit = TimeUnit.MILLISECONDS) +@Measurement(iterations = 20, time = 200, timeUnit = TimeUnit.MILLISECONDS) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +public class ImportedModelCodegenBenchmark extends AbstractCodegenBenchmark { + + @Override + protected String getResource() { + return "dmn/Importing_EmptyNamed_Model_With_Href_Namespace.dmn"; + } + + @Override + protected List getAdditionalResources() { + return List.of("dmn/Imported_Model_Unamed.dmn"); + } + + @Override + protected String getNameSpace() { + return "http://www.trisotech.com/dmn/definitions/_f79aa7a4-f9a3-410a-ac95-bea496edabgc"; + } + + @Override + protected String getModelName() { + return "Importing empty-named Model"; + } + + @Override + protected Map getInputData() { + Map aPerson = prototype(entry("name", "John"), entry("age", 20)); + Map anImportedPerson = prototype(entry("name", "Luke"), entry("age", 35)); + return prototype(entry("A Person", aPerson), entry("An Imported Person", anImportedPerson)); + } + + @Setup() + public void setupModelAndContext() { + super.setupModelAndContext(); + } + + @Benchmark + public Object evaluateModelBenchmark() { + return super.evaluateModelBenchmark(); + } + + public static void main(String[] args) throws Exception { + ImportedModelCodegenBenchmark a = new ImportedModelCodegenBenchmark(); + a.setupModelAndContext(); + System.out.println(a.evaluateModelBenchmark()); + } + + +} diff --git a/drools-benchmarks-parent/drools-benchmarks/src/main/java/org/drools/benchmarks/dmn/codegen/PrequalificationCodegenBenchmark.java b/drools-benchmarks-parent/drools-benchmarks/src/main/java/org/drools/benchmarks/dmn/codegen/PrequalificationCodegenBenchmark.java new file mode 100644 index 00000000..15600b89 --- /dev/null +++ b/drools-benchmarks-parent/drools-benchmarks/src/main/java/org/drools/benchmarks/dmn/codegen/PrequalificationCodegenBenchmark.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.dmn.codegen; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import static org.drools.benchmarks.dmn.util.DynamicTypeUtils.entry; +import static org.drools.benchmarks.dmn.util.DynamicTypeUtils.prototype; + +@BenchmarkMode(Mode.AverageTime) +@State(Scope.Thread) +@Warmup(iterations = 100, time = 200, timeUnit = TimeUnit.MILLISECONDS) +@Measurement(iterations = 20, time = 200, timeUnit = TimeUnit.MILLISECONDS) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +public class PrequalificationCodegenBenchmark extends AbstractCodegenBenchmark { + + @Override + protected String getResource() { + return "dmn/Prequalification.dmn"; + } + + @Override + protected List getAdditionalResources() { + return null; + } + + @Override + protected String getNameSpace() { + return "http://www.trisotech.com/definitions/_f31e1f8e-d4ce-4a3a-ac3b-747efa6b3401"; + } + + @Override + protected String getModelName() { + return "Prequalification"; + } + + @Override + protected Map getInputData() { + Map borrower = prototype(entry("Monthly Income", 100), entry("Monthly Other Debt", 20)); + return prototype(entry("Credit Score", 350), + entry("Loan Amount", 15), + entry("Appraised Value", 10), + entry("Best Rate", 5), + entry("Borrower", borrower)); + } + + @Setup() + public void setupModelAndContext() { + super.setupModelAndContext(); + } + + @Benchmark + public Object evaluateModelBenchmark() { + return super.evaluateModelBenchmark(); + } + + + public static void main(String[] args) throws Exception { + PrequalificationCodegenBenchmark a = new PrequalificationCodegenBenchmark(); + a.setupModelAndContext(); + System.out.println(a.evaluateModelBenchmark()); + } + + +} diff --git a/drools-benchmarks-parent/drools-benchmarks/src/main/resources/dmn/Imported_Model_Unamed.dmn b/drools-benchmarks-parent/drools-benchmarks/src/main/resources/dmn/Imported_Model_Unamed.dmn new file mode 100644 index 00000000..d5508b66 --- /dev/null +++ b/drools-benchmarks-parent/drools-benchmarks/src/main/resources/dmn/Imported_Model_Unamed.dmn @@ -0,0 +1,86 @@ + + + + + + + + + string + + + number + + + + + + + + + + + + + + + + + + Say Hello( An Imported Person ) + + + + + + + + + "Hello " + Person.name + "!" + + + + + diff --git a/drools-benchmarks-parent/drools-benchmarks/src/main/resources/dmn/Importing_EmptyNamed_Model_With_Href_Namespace.dmn b/drools-benchmarks-parent/drools-benchmarks/src/main/resources/dmn/Importing_EmptyNamed_Model_With_Href_Namespace.dmn new file mode 100644 index 00000000..71587298 --- /dev/null +++ b/drools-benchmarks-parent/drools-benchmarks/src/main/resources/dmn/Importing_EmptyNamed_Model_With_Href_Namespace.dmn @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + Local Hello( A Person ) + + + + + + + + + + + + + Say Hello( A Person ) + + + + + + + + + "Local Hello " + Person.name + "!" + + + + + diff --git a/drools-benchmarks-parent/drools-benchmarks/src/main/resources/dmn/Prequalification.dmn b/drools-benchmarks-parent/drools-benchmarks/src/main/resources/dmn/Prequalification.dmn new file mode 100644 index 00000000..d403e76d --- /dev/null +++ b/drools-benchmarks-parent/drools-benchmarks/src/main/resources/dmn/Prequalification.dmn @@ -0,0 +1,856 @@ + + + + + + + string + + + + "High", "Medium", "Low" + + "High" + "High" + + + "Medium" + "Medium" + + + "Low" + "Low" + + + + "High","Medium","Low" + + + + number + + + + [300..850] + + + [300..850] + + + + string + + + + "Excellent", "Good", "Problem", "Not a client" + + "Excellent" + "Excellent" + + + "Good" + "Good" + + + "Problem" + "Problem" + + + "Not a client" + "Not a client" + + + + "Excellent","Good","Problem","Not a client" + + + + + number + + + number + + + number + + + + string + + + + "Approved", "Declined" + + "Approved" + "Approved" + + + "Declined" + "Declined" + + + + "Approved","Declined" + + + + + number + + + number + + + + string + + + + "Approved", "Declined" + + "Approved" + "Approved" + + + "Declined" + "Declined" + + + + "Approved","Declined" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LTV + + + + + DTI + + + + + Credit Score + + + [300..850] + + + + + "Approved","Declined" + + + + + + <=0.75 + + + <=0.36 + + + >=620 + + + "Approved" + + + + + + + + <=0.75 + + + (0.36..0.45] + + + >=640 + + + "Approved" + + + + + + + + (0.75..0.80] + + + <=0.36 + + + >=680 + + + "Approved" + + + + + + + + (0.75..0.80] + + + (0.36..0.45] + + + >=700 + + + "Approved" + + + + + + + + - + + + - + + + - + + + "Declined" + + + + + + + + + + Qualification = "Approved" + + + + + + + + + + + + + + (Loan Payment+Borrower.Monthly Other Debt)/Borrower.Monthly Income + + + + + + + + + + + + + + + + + + + + + + + + LLPA*.00125 + Best Rate + + + + + + + payment + + + + + Loan Amount + + + + + + adjustedRate + + + + + + 360 + + + + + + + decimal( amount, 2 ) + + + + + + + + + + + + + + + + + + + + Loan Amount/Appraised Value + + + + + + + + + + + + + + + + principal*rate/12/(1-(1+rate/12)**-term) + + + + + + + + + + + + + + + LTV + + + + + Credit Score + + + [300..850] + + + + + + + <=0.60 + + + >=660 + + + 0 + + + + + + + + <=0.60 + + + [620..660) + + + 0.5 + + + + + + + + (0.60..0.70] + + + >=720 + + + 0.25 + + + + + + + + (0.60..0.70] + + + [680..720) + + + 0.5 + + + + + + + + (0.60..0.70] + + + [660..680) + + + 1.0 + + + + + + + + (0.60..0.70] + + + [640..660) + + + 1.25 + + + + + + + + (0.60..0.70] + + + [620..640) + + + 1.5 + + + + + + + + (0.70..0.75] + + + >=740 + + + 0.25 + + + + + + + + (0.70..0.75] + + + [720..740) + + + 0.5 + + + + + + + + (0.70..0.75] + + + [700..720) + + + 1.0 + + + + + + + + (0.70..0.75] + + + [680..700) + + + 1.25 + + + + + + + + (0.70..0.75] + + + [660..680) + + + 2.25 + + + + + + + + (0.70..0.75] + + + [640..660) + + + 2.75 + + + + + + + + (0.70..0.75] + + + [620..640) + + + 3.0 + + + + + + + + (0.75..0.80] + + + >=740 + + + 0.5 + + + + + + + + (0.75..0.80] + + + [720..740) + + + 0.75 + + + + + + + + (0.75..0.80] + + + [700..720) + + + 1.25 + + + + + + + + (0.75..0.80] + + + [680..700) + + + 1.75 + + + + + + + + (0.75..0.80] + + + [660..680) + + + 2.75 + + + + + + + + (0.75..0.80] + + + [620..660) + + + 3.0 + + + + + + + + - + + + <620 + + + 4 + + + + + + + + >0.80 + + + - + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file