performance issue with nullable value type

forax at univ-mlv.fr forax at univ-mlv.fr
Tue Jan 8 09:06:18 UTC 2019


----- Mail original -----
> De: "Tobias Hartmann" <tobias.hartmann at oracle.com>
> À: "Remi Forax" <forax at univ-mlv.fr>, "valhalla-dev" <valhalla-dev at openjdk.java.net>
> Envoyé: Lundi 7 Janvier 2019 16:44:01
> Objet: Re: performance issue with nullable value type

> Hi Remi,

Hi Tobias,

> 
> thanks for running these experiments. The results are expected because we currently don't attempt
> scalarization in compiled code for nullable value types (we only scalarize if
> the value type is declared to be non-null or if we can statically prove that it is never null).
> 
> To improve performance, we need to implement something like John's proposal:
> http://cr.openjdk.java.net/~jrose/values/nullable-values.html

I think it's more general than John's proposal, given the perf cliff, i think all boxes should have a scalarized representation for local variables independently from the fact that as a user i may want to indicate to the VM how to represent null for a specific nullable value type.
It's like with hashCode, either the user provides a hashCode or the VM give you one, here, either the user indicates which field means that the value type is null if zero or the VM has to come with a way to represent null as a scalarized variable anyway. 

> 
> Best regards,
> Tobias

best regards,
Rémi

> 
> 
> On 07.01.19 15:44, Remi Forax wrote:
>> Hi all,
>> with the last patch of Tobias, i was able to write a code that iterate an over
>> array with a value type nullable or not.
>> 
>> The first way is to use a non nullable value type + a method hasNext() that
>> indicate if the cursor is at the end
>> 
>>   static value class FlatCursor {
>>     private final int[] array;
>>     private final int index;
>>     
>>     private FlatCursor(int[] array, int index) {
>>       this.array = array;
>>       this.index = index;
>>     }
>>     
>>     Tuple current() {
>>       return new Tuple(index, array[index]);
>>     }
>>     
>>     boolean hasNext() {
>>       return index < array.length;
>>     }
>>     
>>     FlatCursor next() {
>>       return new FlatCursor(array, index + 1);
>>     }
>>   }
>>   
>>   private static FlatCursor flatIndexedElements(int[] array) {
>>     return new FlatCursor(array, 0);
>>   }
>> 
>>   public int sum_flat_indexedElements() {
>>     var sum = 0;
>>     for(var cursor = flatIndexedElements(ARRAY); cursor.hasNext(); cursor =
>>     cursor.next()) {
>>       var tuple = cursor.current();
>>       sum += tuple.index + tuple.element;
>>     }
>>     return sum;
>>   }
>> 
>> the second version is to use a nullable value type and stop if it's null
>> 
>>   static value class Cursor {
>>     private final int[] array;
>>     private final int index;
>>     
>>     private Cursor(int[] array, int index) {
>>       this.array = array;
>>       this.index = index;
>>     }
>>     
>>     Tuple current() {
>>       return new Tuple(index, array[index]);
>>     }
>>     
>>     Cursor.box next() {
>>       Cursor.box box;
>>       if (index + 1 == array.length) {
>>         box = null;
>>       } else {
>>         box = new Cursor(array, index + 1);
>>       }
>>       return box;
>>     }
>>   }
>>   
>>   private static Cursor.box indexedElements(int[] array) {
>>     Cursor.box box;
>>     if (array.length == 0) {
>>       box = null;
>>     } else {
>>       box = new Cursor(array, 0);
>>     }
>>     return box;
>>   }
>>   
>>   private static Cursor fix(Cursor.box cursor) {
>>     return cursor;
>>   }
>> 
>>   public int sum_indexedElements() {
>>     var sum = 0;
>>     for(var cursor = indexedElements(ARRAY); cursor != null; cursor =
>>     fix(cursor).next()) {
>>       var tuple = fix(cursor).current();
>>       sum += tuple.index + tuple.element;
>>     }
>>     return sum;
>>   }
>>   
>> 
>> The main issue is that the version is that it's very slow compared to the non
>> nullable version
>> (the sum_loop is the version is just a plain loop)
>> Benchmark                                    Mode  Cnt    Score   Error  Units
>> TupleLoopBenchMark.sum_flat_indexedElements  avgt    9   41.514 ± 0.156  us/op
>> TupleLoopBenchMark.sum_indexedElements       avgt    9  332.060 ± 4.846  us/op
>> TupleLoopBenchMark.sum_loop                  avgt    9   41.169 ± 0.384  us/op
>> 
>> 
>> I believe that if a nullable value type is on stack, the VM should try to
>> flatten the type by adding a boolean indicating if the value is null or not.
>> 
>> Rémi


More information about the valhalla-dev mailing list