2222package  com .github .packageurl ;
2323
2424import  java .nio .charset .StandardCharsets ;
25+ import  java .util .Locale ;
2526import  java .util .Random ;
2627import  java .util .concurrent .TimeUnit ;
2728import  org .openjdk .jmh .annotations .Benchmark ;
3031import  org .openjdk .jmh .annotations .OutputTimeUnit ;
3132import  org .openjdk .jmh .annotations .Param ;
3233import  org .openjdk .jmh .annotations .Scope ;
33- import  org .openjdk .jmh .annotations .Setup ;
3434import  org .openjdk .jmh .annotations .State ;
3535import  org .openjdk .jmh .infra .Blackhole ;
3636
@@ -62,14 +62,8 @@ public class PercentEncodingBenchmark {
6262    @ Param ({"0" , "0.1" , "0.5" })
6363    private  double  nonAsciiProb ;
6464
65-     private  String [] decodedData  = createDecodedData ();
66-     private  String [] encodedData  = encodeData (decodedData );
67- 
68-     @ Setup 
69-     public  void  setup () {
70-         decodedData  = createDecodedData ();
71-         encodedData  = encodeData (encodedData );
72-     }
65+     private  final  String [] decodedData  = createDecodedData ();
66+     private  final  String [] encodedData  = encodeData (decodedData );
7367
7468    private  String [] createDecodedData () {
7569        Random  random  = new  Random ();
@@ -90,8 +84,11 @@ private String[] createDecodedData() {
9084
9185    private  static  String [] encodeData (String [] decodedData ) {
9286        String [] encodedData  = new  String [decodedData .length ];
93-         for  (int  i  = 0 ; i  < decodedData .length ; i ++) {
87+         for  (int  i  = 0 ; i  < encodedData .length ; i ++) {
9488            encodedData [i ] = PackageURL .percentEncode (decodedData [i ]);
89+             if  (!PackageURL .percentDecode (encodedData [i ]).equals (decodedData [i ])) {
90+                 throw  new  RuntimeException ("Invalid implementation of `percentEncode` and `percentDecode`." );
91+             }
9592        }
9693        return  encodedData ;
9794    }
@@ -100,17 +97,28 @@ private static String[] encodeData(String[] decodedData) {
10097    public  void  baseline (Blackhole  blackhole ) {
10198        for  (int  i  = 0 ; i  < DATA_COUNT ; i ++) {
10299            byte [] buffer  = decodedData [i ].getBytes (StandardCharsets .UTF_8 );
103-             // Change  the String a little bit  
100+             // Prevent JIT compiler from assuming  the buffer was not modified  
104101            for  (int  idx  = 0 ; idx  < buffer .length ; idx ++) {
105-                 byte  b  = buffer [idx ];
106-                 if  ('a'  <= b  && b  <= 'z' ) {
107-                     buffer [idx ] = (byte ) (b  & 0x20 );
108-                 }
102+                 buffer [idx ] ^= 0x20 ;
109103            }
110104            blackhole .consume (new  String (buffer , StandardCharsets .UTF_8 ));
111105        }
112106    }
113107
108+     @ Benchmark 
109+     public  void  toLowerCaseJre (Blackhole  blackhole ) {
110+         for  (int  i  = 0 ; i  < DATA_COUNT ; i ++) {
111+             blackhole .consume (decodedData [i ].toLowerCase (Locale .ROOT ));
112+         }
113+     }
114+ 
115+     @ Benchmark 
116+     public  void  toLowerCase (Blackhole  blackhole ) {
117+         for  (int  i  = 0 ; i  < DATA_COUNT ; i ++) {
118+             blackhole .consume (PackageURL .toLowerCase (decodedData [i ]));
119+         }
120+     }
121+ 
114122    @ Benchmark 
115123    public  void  percentDecode (final  Blackhole  blackhole ) {
116124        for  (int  i  = 0 ; i  < DATA_COUNT ; i ++) {
0 commit comments