Method invokes inefficient Number constructor; use static valueOf instead
PATCH 1/1 Method invokes inefficient Number constructor; use static valueOf instead
Quoted 1 line
From FindBugs:
Using new Integer(int) is guaranteed to always result in a new object whereas Integer.valueOf(int) allows caching of values to be done by the compiler, class library, or JVM. Using of cached values avoids object allocation and the code will be faster.
Values between -128 and 127 are guaranteed to have corresponding cached instances and using valueOf is approximately 3.5 times faster than using constructor. For values outside the constant range the performance of both styles is the same.
--- .../jgit/errors/NoClosingBracketException.java | 4 ++-- .../src/org/spearce/jgit/transport/IndexPack.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-)
org.spearce.jgit/src/org/spearce/jgit/errors/NoClosingBracketException.java +2 -2
@@ -64,7 +64,7 @@ super(createMessage(indexOfOpeningBracket, openingBracket, private static String createMessage(final int indexOfOpeningBracket, final String openingBracket, final String closingBracket) { return String.format("No closing %s found for %s at index %s.", - closingBracket, openingBracket, new Integer( - indexOfOpeningBracket)); + closingBracket, openingBracket, + Integer.valueOf(indexOfOpeningBracket)); } }
org.spearce.jgit/src/org/spearce/jgit/transport/IndexPack.java +3 -3
@@ -383,7 +383,7 @@ private void resolveDeltas(final ProgressMonitor progress) private void resolveDeltas(final PackedObjectInfo oe) throws IOException { final int oldCRC = oe.getCRC(); if (baseById.containsKey(oe) - || baseByPos.containsKey(new Long(oe.getOffset()))) + || baseByPos.containsKey(Long.valueOf(oe.getOffset()))) resolveDeltas(oe.getOffset(), oldCRC, Constants.OBJ_BAD, null, oe); }
@@ -448,7 +448,7 @@ private void resolveDeltas(final long pos, final int oldCRC, int type, private void resolveChildDeltas(final long pos, int type, byte[] data, PackedObjectInfo oe) throws IOException { final ArrayList<UnresolvedDelta> a = baseById.remove(oe); - final ArrayList<UnresolvedDelta> b = baseByPos.remove(new Long(pos)); + final ArrayList<UnresolvedDelta> b = baseByPos.remove(Long.valueOf(pos)); int ai = 0, bi = 0; if (a != null && b != null) { while (ai < a.size() && bi < b.size()) {
@@ -679,7 +679,7 @@ private void indexOneObject() throws IOException { ofs <<= 7; ofs += (c & 127); } - final Long base = new Long(pos - ofs); + final Long base = Long.valueOf(pos - ofs); ArrayList<UnresolvedDelta> r = baseByPos.get(base); if (r == null) { r = new ArrayList<UnresolvedDelta>(8);
Signature · 1 line
1.6.1.2
Quoted 5 lines · Yann Simon
From FindBugs:
Using new Integer(int) is guaranteed to always result in a new object whereasInteger.valueOf(int)allows caching of values to be done by the compiler, class library, or JVM. Using of cached values avoids object allocation and the code will be faster.
Ah, yes.
Quoted 2 lines
Values between -128 and 127 are guaranteed to have corresponding cached instances [...]
...
org.spearce.jgit/src/org/spearce/jgit/transport/IndexPack.java private void resolveDeltas(final ProgressMonitor progress) · line 386
Quoted 10 lines
org.spearce.jgit/src/org/spearce/jgit/transport/IndexPack.java +1
-1@@ -383,7 +383,7 @@ private void resolveDeltas(final ProgressMonitor progress) private void resolveDeltas(final PackedObjectInfo oe) throws IOException { final int oldCRC = oe.getCRC(); if (baseById.containsKey(oe) - || baseByPos.containsKey(new Long(oe.getOffset()))) + || baseByPos.containsKey(Long.valueOf(oe.getOffset())))
Why I box with new Long() over Long.valueOf():
The standard only requires -128..127 to be cached. A JRE can cache value outside of this range if it chooses, but long has a huge range, its unlikely to cache much beyond this required region.
Most pack files are in the 10 MB...100+ MB range. Most objects take more than 100 bytes in a pack, even compressed delta encoded. Thus any object after the first is going to have its offset outside of the cached range.
In other words, why waste the CPU cycles on the "cached range bounds check" when I'm always going to fail and allocate. I might as well just allocate
These sections of code are rather performance critical for the indexing phase of a pack receive, on either side of a connection. I need to shave even more instructions out of the critical paths, as its not fast enough as-is. Using new Long() is quicker than using Long.valueOf(), so new Long() it is.
Quoted 10 lines
org.spearce.jgit/src/org/spearce/jgit/transport/IndexPack.java +1
-1@@ -448,7 +448,7 @@ private void resolveDeltas(final long pos, final int oldCRC, int type, private void resolveChildDeltas(final long pos, int type, byte[] data, PackedObjectInfo oe) throws IOException { final ArrayList<UnresolvedDelta> a = baseById.remove(oe); - final ArrayList<UnresolvedDelta> b = baseByPos.remove(new Long(pos)); + final ArrayList<UnresolvedDelta> b = baseByPos.remove(Long.valueOf(pos)); int ai = 0, bi = 0; if (a != null && b != null) { while (ai < a.size() && bi < b.size()) {
org.spearce.jgit/src/org/spearce/jgit/transport/IndexPack.java private void indexOneObject() throws IOException { · line 683
Quoted 6 lines
org.spearce.jgit/src/org/spearce/jgit/transport/IndexPack.java +1
-1@@ -679,7 +679,7 @@ private void indexOneObject() throws IOException { ofs <<= 7; ofs += (c & 127); } - final Long base = new Long(pos - ofs); + final Long base = Long.valueOf(pos - ofs); ArrayList<UnresolvedDelta> r = baseByPos.get(base);
See above for why these two hunks allocate rather than use valueOf() or even the implicit compiler produced auto-boxing (which uses valueOf).
But your first hunk (which I snipped) is fine to apply.
Signature · 1 line
Shawn.
2009/3/19 Shawn O. Pearce <[email protected]>:
Quoted 15 lines
Why I box with new
Long()overLong.valueOf():The standard only requires -128..127 to be cached. A JRE can cache value outside of this range if it chooses, but long has a huge range, its unlikely to cache much beyond this required region.
Most pack files are in the 10 MB...100+ MB range. Most objects take more than 100 bytes in a pack, even compressed delta encoded. Thus any object after the first is going to have its offset outside of the cached range.
In other words, why waste the CPU cycles on the "cached range bounds check" when I'm always going to fail and allocate. I might as well just allocate
Quoted 5 lines
These sections of code are rather performance critical for the indexing phase of a pack receive, on either side of a connection. I need to shave even more instructions out of the critical paths, as its not fast enough as-is. Using new
Long()is quicker than usingLong.valueOf(), so newLong()it is.
It makes sense.
Thank you for the explanation.
Yann
Quoted 1 line · Yann Simon
From FindBugs:
+1
also, junit would be another +1 AFAIC :-)