From 5a228d2b6fce481a366e7ed02cec3b27f1e70889 Mon Sep 17 00:00:00 2001 From: "Travis CI (pmd-bot)" Date: Fri, 8 Dec 2017 01:56:40 +0000 Subject: [PATCH] Update documentation --- docs/pages/pmd/rules/java.md | 2 +- docs/pages/pmd/rules/java/performance.md | 26 ++++++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/docs/pages/pmd/rules/java.md b/docs/pages/pmd/rules/java.md index 1344abb331..5c2413766c 100644 --- a/docs/pages/pmd/rules/java.md +++ b/docs/pages/pmd/rules/java.md @@ -304,7 +304,7 @@ folder: pmd/rules * [InsufficientStringBufferDeclaration](pmd_rules_java_performance.html#insufficientstringbufferdeclaration): Failing to pre-size a StringBuffer or StringBuilder properly could cause it to re-size many times... * [IntegerInstantiation](pmd_rules_java_performance.html#integerinstantiation): Calling new Integer() causes memory allocation that can be avoided by the static Integer.valueOf(... * [LongInstantiation](pmd_rules_java_performance.html#longinstantiation): Calling new Long() causes memory allocation that can be avoided by the static Long.valueOf().It m... -* [OptimizableToArrayCall](pmd_rules_java_performance.html#optimizabletoarraycall): Calls to a collection's toArray() method should specify target arrays sized to match the size of ... +* [OptimizableToArrayCall](pmd_rules_java_performance.html#optimizabletoarraycall): Calls to a collection's 'toArray(E[])' method should specify a target array of zero size. This al... * [RedundantFieldInitializer](pmd_rules_java_performance.html#redundantfieldinitializer): Java will initialize fields with known default values so any explicit initialization of those sam... * [ShortInstantiation](pmd_rules_java_performance.html#shortinstantiation): Calling new Short() causes memory allocation that can be avoided by the static Short.valueOf().It... * [SimplifyStartsWith](pmd_rules_java_performance.html#simplifystartswith): Since it passes in a literal of length 1, calls to (string).startsWith can be rewritten using (st... diff --git a/docs/pages/pmd/rules/java/performance.md b/docs/pages/pmd/rules/java/performance.md index b2a8525e3b..28982f769e 100644 --- a/docs/pages/pmd/rules/java/performance.md +++ b/docs/pages/pmd/rules/java/performance.md @@ -457,9 +457,19 @@ public class Foo { **Priority:** Medium (3) -Calls to a collection's toArray() method should specify target arrays sized to match the size of the -collection. Initial arrays that are too small are discarded in favour of new ones that have to be created -that are the proper size. +**Minimum Language Version:** Java 1.6 + +Calls to a collection's `toArray(E[])` method should specify a target array of zero size. This allows the JVM +to optimize the memory allocation and copying as much as possible. + +Previous versions of this rule (pre PMD 6.0.0) suggested the opposite, but current JVM implementations +perform always better, when they have full control over the target array. And allocation an array via +reflection is nowadays as fast as the direct allocation. + +See also [Arrays of Wisdom of the Ancients](https://shipilev.net/blog/2016/arrays-wisdom-ancients/) + +Note: If you don't need an array of the correct type, then the simple `toArray()` method without an array +is faster, but returns only an array of type `Object[]`. ``` //PrimaryExpression @@ -467,20 +477,20 @@ that are the proper size. [ PrimarySuffix/Arguments/ArgumentList/Expression /PrimaryExpression/PrimaryPrefix/AllocationExpression - /ArrayDimsAndInits/Expression/PrimaryExpression/PrimaryPrefix/Literal[@Image='0'] + /ArrayDimsAndInits/Expression/PrimaryExpression/PrimaryPrefix[not(Literal[@Image='0'])] ] ``` **Example(s):** ``` java -List foos = getFoos(); +List foos = getFoos(); - // inefficient, the array will be discarded +// much better; this one allows the jvm to allocate an array of the correct size and effectively skip +// the zeroing, since each array element will be overridden anyways Foo[] fooArray = foos.toArray(new Foo[0]); - // much better; this one sizes the destination array, - // avoiding of a new one via reflection +// inefficient, the array needs to be zeroed out by the jvm before it is handed over to the toArray method Foo[] fooArray = foos.toArray(new Foo[foos.size()]); ```