Remove the assert in Integer.valueOf()
Rémi Forax
forax at univ-mlv.fr
Tue May 1 11:15:49 UTC 2012
On 05/01/2012 12:09 AM, Ulf Zibis wrote:
> Hi Rémi,
>
> Am 28.04.2012 00:42, schrieb Rémi Forax:
>>> While you are there:
>>> IntegerCache.cache/high/low are static final, so should be named
>>> _upper case_.
>>
>> Not done because the system property is also spelled in lower case.
> Hm, but does that justify violating very common code conventions?
> IMO it's inconvenient while reading the code.
Yes and no. I agree that it's again the code convention
but I think that it better outline the relation with the system property.
Given that all IDEs can be tweaked to display static finals with a
different color/stroke,
I think this code should not be changed.
>
>>
>>>
>>> Another optimization:
>>> public static Integer valueOf(int i) {
>>> if (i >= 0) {
>>> if (i <= IntegerCache.HIGH)
>>> return IntegerCache.POS[i];
>>> } else {
>>> if (i >= IntegerCache.LOW)
>>> return IntegerCache.NEG[~i];
>>> }
>>> return new Integer(i);
>>> }
>>>
>>
>> Can you explain a little bit more why it's more efficient ?
> 1. Compare against 0 is little faster than against a constant which
> must be loaded as operand.
Ok, less bytecode but no impact when JITed
> 2. As positive arguments should be more frequent, my version prevents
> from calculating the index every time:
> IntegerCache.cache[i + (-IntegerCache.low)]
I believe the JIT can emit a mov in that case, I will check.
> 3. Client VM would profit from less bytecode instructions to go
> through, as there is less inlining.
Again, I need to test.
>
>> Given that low and high are constant for the JIT, I'm not sure the
>> current code
>> do bounds checking at all.
> I do not understand this. 'i' is not constant, so should be checked.
I was thinking about the array bound checking.
>
> ==========================================
>
> We must be careful with Integer.MAX_VALUE as maximum array size.
> See: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7153247
> and: java.lang.AbstractCollection.MAX_ARRAY_SIZE
This one is another bug, but you will have trouble with
Integer.MAX_VALUE - (-low).
Rémi
>
> Additionally, I think, *the assert is superfluous at all*, as 'high'
> can never be smaller than 127.
> You can see this, if you compact the code:
>
> static {
> // high value may be configured by property
> String cacheHigh =
>
> sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
> /********** no need for variable i : **********/
> int h = 127;
> if (cacheHigh != null) {
> h = Math.max(parseInt(cacheHigh), 127);
> // Maximum array size is Integer.MAX_VALUE
> h = Math.min(h, Integer.MAX_VALUE - (-low));
> /********** little shorter : **********/
> // Maximum array size is Integer.MAX_VALUE
> h = Math.min(Integer.MAX_VALUE - (-low),
> Math.max(parseInt(cacheHigh), 127));
> }
> high = h;
> /********** more simple : **********/
> int h = 0;
> if (cacheHigh != null) {
> // Maximum array size is Integer.MAX_VALUE
> h = Math.min(Integer.MAX_VALUE - (-low),
> parseInt(cacheHigh));
> }
> high = Math.max(h, 127);
> /********** no need for variable h : **********/
> if (cacheHigh != null)
> // Maximum array size is Integer.MAX_VALUE
> high = Math.min(Integer.MAX_VALUE - (-low),
> Math.max(parseInt(cacheHigh), 127));
> else
> high = 127;
> /********** shorter : **********/
> high = (cacheHigh == null) ? 127 :
> // Maximum array size is Integer.MAX_VALUE
> Math.min(Integer.MAX_VALUE - (-low),
> Math.max(parseInt(cacheHigh), 127));
> /********** most short : **********/
> // Maximum array size is Integer.MAX_VALUE
> high = Math.max(127, Math.min((cacheHigh == null) ? 127 :
> parseInt(cacheHigh), Integer.MAX_VALUE - (-low)));
>
> assert IntegerCache.high >= 127;
>
> // range [-128, 127] must be interned (JLS7 5.1.7)
> cache = new Integer[(high - low) + 1];
> for(int j = low, k = 0; k < cache.length; k++, j++)
> cache[k] = new Integer(j);
> }
>
>
> -Ulf
>
More information about the core-libs-dev
mailing list