Skip to content

Commit 2447bc4

Browse files
committed
Some insights on discussion brough up in #157
1 parent 413b4b7 commit 2447bc4

File tree

1 file changed

+244
-0
lines changed

1 file changed

+244
-0
lines changed
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
package com.networknt.schema;
2+
3+
import com.fasterxml.jackson.databind.JsonNode;
4+
import com.fasterxml.jackson.databind.node.DecimalNode;
5+
import com.fasterxml.jackson.databind.node.DoubleNode;
6+
import com.fasterxml.jackson.databind.node.TextNode;
7+
import org.junit.Ignore;
8+
import org.junit.Test;
9+
10+
import java.lang.reflect.InvocationTargetException;
11+
import java.math.BigDecimal;
12+
13+
@Ignore
14+
public class ThresholdMixinPerfTest {
15+
16+
// private final double threshold = Double.MAX_VALUE - 1;
17+
private final double threshold = 1797693.134E+5D;
18+
private final DoubleNode maximumDouble = new DoubleNode(threshold);
19+
private final DecimalNode maximumDecimal = new DecimalNode(BigDecimal.valueOf(threshold));
20+
21+
private final double value = threshold+1;
22+
private final DoubleNode valueDouble = new DoubleNode(value);
23+
private final DecimalNode valueDecimal = new DecimalNode(new BigDecimal(value));
24+
private final TextNode valueTextual = new TextNode(String.valueOf(value));
25+
26+
private final String maximumText = maximumDouble.asText();
27+
private final BigDecimal max = new BigDecimal(maximumText);
28+
29+
private final int executeTimes = 200000;
30+
private final boolean excludeEqual = false;
31+
32+
@Test
33+
public void testDoubleVsBigDecimalOnCompareTimeViaMixins() throws InvocationTargetException, IllegalAccessException {
34+
35+
double baseTime = getAvgTimeViaMixin(asDouble, valueDouble, executeTimes);
36+
System.out.println(String.format("Base execution time (comparing two DoubleNodes) %f ns \n", baseTime));
37+
38+
double currentAvgTimeOnDouble = getAvgTimeViaMixin(currentImplementationDouble, valueDouble, executeTimes);
39+
System.out.println(String.format("Current double on double execution time %f ns, %f times slower", currentAvgTimeOnDouble, (currentAvgTimeOnDouble/baseTime)));
40+
41+
double currentAvgTimeOnDecimal = getAvgTimeViaMixin(currentImplementationDouble, valueDecimal, executeTimes);
42+
System.out.println(String.format("Current double on decimal execution time %f ns, %f times slower", currentAvgTimeOnDecimal, (currentAvgTimeOnDecimal/baseTime)));
43+
44+
double currentAvgTimeOnText = getAvgTimeViaMixin(currentImplementationDouble, valueTextual, executeTimes);
45+
System.out.println(String.format("Current double on text execution time %f ns, %f times slower", currentAvgTimeOnText, (currentAvgTimeOnText/baseTime)));
46+
47+
double currentAvgTimeDecimalOnDouble = getAvgTimeViaMixin(currentImplementationDecimal, valueDouble, executeTimes);
48+
System.out.println(String.format("Current decimal on double execution time %f ns, %f times slower", currentAvgTimeDecimalOnDouble, (currentAvgTimeDecimalOnDouble/baseTime)));
49+
50+
double currentAvgTimeDecimalOnDecimal = getAvgTimeViaMixin(currentImplementationDecimal, valueDecimal, executeTimes);
51+
System.out.println(String.format("Current decimal on decimal execution time %f ns, %f times slower", currentAvgTimeDecimalOnDecimal, (currentAvgTimeDecimalOnDecimal/baseTime)));
52+
53+
double currentAvgTimeDecimalOnText = getAvgTimeViaMixin(currentImplementationDecimal, valueTextual, executeTimes);
54+
System.out.println(String.format("Current decimal on text execution time %f ns, %f times slower", currentAvgTimeDecimalOnText, (currentAvgTimeDecimalOnText/baseTime)));
55+
56+
System.out.println(String.format("Cumulative average: %f\n\n", (currentAvgTimeOnDouble+currentAvgTimeOnDecimal+currentAvgTimeOnText+currentAvgTimeDecimalOnDouble+currentAvgTimeDecimalOnDecimal+currentAvgTimeDecimalOnText)/6.0d));
57+
58+
double allInOneDoubleOnDouble = getAvgTimeViaMixin(allInOneDouble, valueDouble, executeTimes);
59+
System.out.println(String.format("AllInOne double on double execution time %f ns, %f times slower", allInOneDoubleOnDouble, (allInOneDoubleOnDouble/baseTime)));
60+
61+
double allInOneDoubleOnDecimal = getAvgTimeViaMixin(allInOneDouble, valueDecimal, executeTimes);
62+
System.out.println(String.format("AllInOne double on decimal execution time %f ns, %f times slower", allInOneDoubleOnDecimal, (allInOneDoubleOnDecimal/baseTime)));
63+
64+
double allInOneDoubleOnText = getAvgTimeViaMixin(allInOneDouble, valueTextual, executeTimes);
65+
System.out.println(String.format("AllInOne double on text execution time %f ns, %f times slower", allInOneDoubleOnText, (allInOneDoubleOnText/baseTime)));
66+
67+
double allInOneDecimalOnDouble = getAvgTimeViaMixin(allInOneDecimal, valueDouble, executeTimes);
68+
System.out.println(String.format("AllInOne decimal on double execution time %f ns, %f times slower", allInOneDecimalOnDouble, (allInOneDecimalOnDouble/baseTime)));
69+
70+
double allInOneDecimalOnDecimal = getAvgTimeViaMixin(allInOneDecimal, valueDecimal, executeTimes);
71+
System.out.println(String.format("AllInOne decimal on decimal execution time %f ns, %f times slower", allInOneDecimalOnDecimal, (allInOneDecimalOnDecimal/baseTime)));
72+
73+
double allInOneDecimalOnText = getAvgTimeViaMixin(allInOneDecimal, valueTextual, executeTimes);
74+
System.out.println(String.format("AllInOne decimal on text execution time %f ns, %f times slower", allInOneDecimalOnText, (allInOneDecimalOnText/baseTime)));
75+
76+
System.out.println(String.format("Cumulative average: %f\n\n", (allInOneDoubleOnDouble+allInOneDoubleOnDecimal+allInOneDoubleOnText+allInOneDecimalOnDouble+allInOneDecimalOnDecimal+allInOneDecimalOnText)/6.0d));
77+
78+
double typedThresholdOnDouble = getAvgTimeViaMixin(typedThreshold, valueDouble, executeTimes);
79+
System.out.println(String.format("Typed threshold execution time %f ns, %f times slower", typedThresholdOnDouble, (typedThresholdOnDouble/baseTime)));
80+
81+
double typedThresholdOnDecimal = getAvgTimeViaMixin(typedThreshold, valueDecimal, executeTimes);
82+
System.out.println(String.format("Typed threshold execution time %f ns, %f times slower", typedThresholdOnDecimal, (typedThresholdOnDecimal/baseTime)));
83+
84+
double typedThresholdOnText = getAvgTimeViaMixin(typedThreshold, valueTextual, executeTimes);
85+
System.out.println(String.format("Typed threshold execution time %f ns, %f times slower", typedThresholdOnText, (typedThresholdOnText/baseTime)));
86+
87+
System.out.println(String.format("Cumulative average: %f\n\n", (typedThresholdOnDouble+typedThresholdOnDecimal+typedThresholdOnText)/3.0d));
88+
}
89+
90+
ThresholdMixin allInOneDouble = new AllInOneThreshold(maximumDouble, false);
91+
ThresholdMixin allInOneDecimal = new AllInOneThreshold(maximumDecimal, false);
92+
93+
public static class AllInOneThreshold implements ThresholdMixin {
94+
95+
private final BigDecimal bigDecimalMax;
96+
JsonNode maximum;
97+
private boolean excludeEqual;
98+
99+
AllInOneThreshold(JsonNode maximum, boolean exludeEqual){
100+
this.maximum = maximum;
101+
this.excludeEqual = exludeEqual;
102+
this.bigDecimalMax = new BigDecimal(maximum.asText());
103+
}
104+
105+
@Override
106+
public boolean crossesThreshold(JsonNode node) {
107+
if (maximum.isDouble() && maximum.doubleValue() == Double.POSITIVE_INFINITY) {
108+
return false;
109+
}
110+
if (maximum.isDouble() && maximum.doubleValue() == Double.NEGATIVE_INFINITY) {
111+
return true;
112+
}
113+
if (maximum.isDouble() && node.isDouble()) {
114+
double lm = maximum.doubleValue();
115+
double val = node.doubleValue();
116+
return lm < val || (excludeEqual && lm == val);
117+
}
118+
119+
if (maximum.isFloatingPointNumber() && node.isFloatingPointNumber()) {
120+
BigDecimal value = node.decimalValue();
121+
int compare = value.compareTo(bigDecimalMax);
122+
return compare > 0 || (excludeEqual && compare == 0);
123+
}
124+
125+
BigDecimal value = new BigDecimal(node.asText());
126+
int compare = value.compareTo(bigDecimalMax);
127+
return compare > 0 || (excludeEqual && compare == 0);
128+
}
129+
130+
@Override
131+
public String thresholdValue() {
132+
return maximum.asText();
133+
}
134+
};
135+
136+
ThresholdMixin asDouble = new ThresholdMixin() {
137+
@Override
138+
public boolean crossesThreshold(JsonNode node) {
139+
double lm = maximumDouble.doubleValue();
140+
double val = node.doubleValue();
141+
return lm < val || (excludeEqual && lm == val);
142+
}
143+
144+
@Override
145+
public String thresholdValue() {
146+
return maximumText;
147+
}
148+
};
149+
150+
ThresholdMixin typedThreshold = new ThresholdMixin() {
151+
@Override
152+
public boolean crossesThreshold(JsonNode node) {
153+
if (node.isDouble()) {
154+
double lm = maximumDouble.doubleValue();
155+
double val = node.doubleValue();
156+
return lm < val || (excludeEqual && lm == val);
157+
}
158+
159+
if (node.isBigDecimal()) {
160+
BigDecimal value = node.decimalValue();
161+
int compare = value.compareTo(max);
162+
return compare > 0 || (excludeEqual && compare == 0);
163+
}
164+
165+
BigDecimal value = new BigDecimal(node.asText());
166+
int compare = value.compareTo(max);
167+
return compare > 0 || (excludeEqual && compare == 0);
168+
}
169+
170+
@Override
171+
public String thresholdValue() {
172+
return maximumText;
173+
}
174+
};
175+
176+
ThresholdMixin currentImplementationDouble = new ThresholdMixin() {
177+
@Override
178+
public boolean crossesThreshold(JsonNode node) {
179+
if (maximumDouble.isDouble() && maximumDouble.doubleValue() == Double.POSITIVE_INFINITY) {
180+
return false;
181+
}
182+
if (maximumDouble.isDouble() && maximumDouble.doubleValue() == Double.NEGATIVE_INFINITY) {
183+
return true;
184+
}
185+
if (node.isDouble() && node.doubleValue() == Double.NEGATIVE_INFINITY) {
186+
return false;
187+
}
188+
if (node.isDouble() && node.doubleValue() == Double.POSITIVE_INFINITY) {
189+
return true;
190+
}
191+
final BigDecimal max = new BigDecimal(maximumText);
192+
BigDecimal value = new BigDecimal(node.asText());
193+
int compare = value.compareTo(max);
194+
return compare > 0 || (excludeEqual && compare == 0);
195+
}
196+
197+
@Override
198+
public String thresholdValue() {
199+
return maximumText;
200+
}
201+
};
202+
203+
204+
ThresholdMixin currentImplementationDecimal = new ThresholdMixin() {
205+
@Override
206+
public boolean crossesThreshold(JsonNode node) {
207+
if (maximumDecimal.isDouble() && maximumDecimal.doubleValue() == Double.POSITIVE_INFINITY) {
208+
return false;
209+
}
210+
if (maximumDecimal.isDouble() && maximumDecimal.doubleValue() == Double.NEGATIVE_INFINITY) {
211+
return true;
212+
}
213+
if (node.isDouble() && node.doubleValue() == Double.NEGATIVE_INFINITY) {
214+
return false;
215+
}
216+
if (node.isDouble() && node.doubleValue() == Double.POSITIVE_INFINITY) {
217+
return true;
218+
}
219+
final BigDecimal max = new BigDecimal(maximumText);
220+
BigDecimal value = new BigDecimal(node.asText());
221+
int compare = value.compareTo(max);
222+
return compare > 0 || (excludeEqual && compare == 0);
223+
}
224+
225+
@Override
226+
public String thresholdValue() {
227+
return maximumText;
228+
}
229+
};
230+
231+
private double getAvgTimeViaMixin(ThresholdMixin mixin, JsonNode value, int iterations) {
232+
boolean excludeEqual = false;
233+
long totalTime = 0;
234+
for(int i = 0; i < iterations; i++) {
235+
long start = System.nanoTime();
236+
try {
237+
mixin.crossesThreshold(value);
238+
} finally {
239+
totalTime += System.nanoTime() - start;
240+
}
241+
}
242+
return totalTime / (iterations * 1.0D);
243+
}
244+
}

0 commit comments

Comments
 (0)