[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