[10] RFR 8134512 : provide Alpha-Numeric (logical) Comparator
Peter Levart
peter.levart at gmail.com
Sun Jul 30 07:36:01 UTC 2017
Hi Ivan,
On 07/29/2017 07:22 PM, Peter Levart wrote:
> I tried an approach where sub-sequences are CharSequence objects by
> delegation and use sub-comparators that don't convert CharSequence(s)
> to String(s). Here's what this looks like:
>
> http://cr.openjdk.java.net/~plevart/misc/AlphadecimalComparator/alphadecimal-comparator/src/main/java/peter/AlphadecimalComparator.java
>
> Here are the results:
>
> http://cr.openjdk.java.net/~plevart/misc/AlphadecimalComparator/alphadecimal-comparator/bench_results_speed.txt
A simple optimization of above code (manually unrolling the
alpha/decimal alteration - i.e. getting rid of 'alpha' boolean flag):
before:
boolean alpha = true;
while (true) {
if (ss1.next(alpha)) {
if (ss2.next(alpha)) {
Comparator<? super CharSequence>
comparator = alpha
? alphaComparator
: decimalComparator;
int cmp = comparator.compare(ss1, ss2);
if (cmp != 0) {
return cmp;
}
} else {
return 1;
}
} else {
if (ss2.next(alpha)) {
return -1;
} else {
return 0;
}
}
alpha = !alpha;
}
after:
while (true) {
// alpha part
if (ss1.next(true)) {
if (ss2.next(true)) {
int cmp = alphaComparator.compare(ss1, ss2);
if (cmp != 0) {
return cmp;
}
} else {
return 1;
}
} else {
if (ss2.next(true)) {
return -1;
} else {
return 0;
}
}
// decimal part
if (ss1.next(false)) {
if (ss2.next(false)) {
int cmp = decimalComparator.compare(ss1, ss2);
if (cmp != 0) {
return cmp;
}
} else {
return 1;
}
} else {
if (ss2.next(false)) {
return -1;
} else {
return 0;
}
}
}
...yields a noticeable spead-up:
// reference:
Benchmark (_strings) (comparator) Mode Cnt
Score Error Units
ComparatorBench.test strings1 ivan.NumericComparator avgt 10
1455.789 ± 37.158 ns/op
ComparatorBench.test strings2 ivan.NumericComparator avgt 10
13680.131 ± 338.763 ns/op
// before explicit alpha/decimal alteration unrolling:
Benchmark (_strings) (comparator) Mode
Cnt Score Error Units
ComparatorBench.test strings1 peter.AlphadecimalComparator.CS avgt
10 2065.324 ± 50.532 ns/op
ComparatorBench.test strings2 peter.AlphadecimalComparator.CS avgt
10 21118.430 ± 350.769 ns/op
// after explicit alpha/decimal alteration unrolling:
Benchmark (_strings) (comparator) Mode
Cnt Score Error Units
ComparatorBench.test strings1 peter.AlphadecimalComparator.CS avgt
10 1692.145 ± 2.160 ns/op
ComparatorBench.test strings2 peter.AlphadecimalComparator.CS avgt
10 18624.677 ± 1900.779 ns/op
With this mod, AlphadecimalComparator is only about 16 - 35% slower than
NumericComparator.
Regards, Peter
More information about the core-libs-dev
mailing list