These rules deal with different optimizations that generally apply to performance best practices.
A local variable assigned only once can be declared final.
This rule is defined by the following Java class: net.sourceforge.pmd.rules.optimization.LocalVariableCouldBeFinal
Here's an example of code that would trigger this rule:
public class Bar { public void foo () { String a = "a"; //if a will not be assigned again it is better to do this: final String b = "b"; } }
A method argument that is never assigned can be declared final.
This rule is defined by the following Java class: net.sourceforge.pmd.rules.optimization.MethodArgumentCouldBeFinal
Here's an example of code that would trigger this rule:
public void foo (String param) { // do stuff with param never assigning it // better: public void foo (final String param) { }
Detects when a new object is created inside a loop
This rule is defined by the following Java class: net.sourceforge.pmd.rules.optimization.AvoidInstantiatingObjectsInLoops
Here's an example of code that would trigger this rule:
public class Something { public static void main( String as[] ) { for (int i = 0; i < 10; i++) { Foo f = new Foo(); //Avoid this whenever you can it's really expensive } } }
ArrayList is a much better Collection implementation than Vector.
This rule is defined by the following XPath expression:
//AllocationExpression /ClassOrInterfaceType[@Image='Vector' or @Image='java.util.Vector']
Here's an example of code that would trigger this rule:
public class SimpleTest extends TestCase { public void testX() { Collection c = new Vector(); // This achieves the same with much better performance // Collection c = new ArrayList(); } }
Since it passes in a literal of length 1, this call to String.startsWith can be rewritten using String.charAt(0) to save some time.
This rule is defined by the following XPath expression:
//PrimaryExpression [PrimaryPrefix/Name [ends-with(@Image, '.startsWith')]] [PrimarySuffix/Arguments/ArgumentList /Expression/PrimaryExpression/PrimaryPrefix /Literal [string-length(@Image)=3] [starts-with(@Image, '"')] [ends-with(@Image, '"')] ]
Here's an example of code that would trigger this rule:
public class Foo { boolean checkIt(String x) { return x.startsWith("a"); } }
Finds usages of += for appending strings.
This rule is defined by the following XPath expression:
//StatementExpression [PrimaryExpression/PrimaryPrefix/Name [@Image = ancestor::MethodDeclaration//LocalVariableDeclaration [./Type//ClassOrInterfaceType[@Image = 'String']]/VariableDeclarator/VariableDeclaratorId/@Image]] //AssignmentOperator[@Compound='true']
Here's an example of code that would trigger this rule:
public class Foo { void bar() { String a; a = "foo"; a += " bar"; // better would be: // StringBuffer a = new StringBuffer("foo"); // a.append(" bar); } }
The class java.util.Arrays has a "asList" method that should be use when you want to create a new List from an array of objects. It is faster than executing a loop to cpy all the elements of the array one by one
This rule is defined by the following XPath expression:
//Statement[ (ForStatement) and (count(.//IfStatement)=0) ] //StatementExpression[ PrimaryExpression/PrimaryPrefix/Name[ @Image = concat(ancestor::MethodDeclaration//LocalVariableDeclaration[ ./Type//ClassOrInterfaceType[ @Image = 'List' or @Image ='ArrayList' ] ] /VariableDeclarator/VariableDeclaratorId[ count(..//AllocationExpression/ClassOrInterfaceType[ @Image="ArrayList" ] )=1 ]/@Image,".add") ] and PrimaryExpression/PrimarySuffix/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix/Name [@Image = ancestor::MethodDeclaration//LocalVariableDeclaration [@Array="true"]/VariableDeclarator/VariableDeclaratorId/@Image] /../..[count(.//PrimarySuffix) =1]/PrimarySuffix/Expression/PrimaryExpression/PrimaryPrefix /Name ]
Here's an example of code that would trigger this rule:
public class Test { public void foo(Integer[] ints) { // could just use Arrays.asList(ints) List l= new ArrayList(10); for (int i=0; i< 100; i++) { l.add(ints[i]); } for (int i=0; i< 100; i++) { l.add(a[i].toString()); // won't trigger the rule } } }
Instead of copying data between two arrays, use System.arrayCopy method
This rule is defined by the following XPath expression:
//Statement[(ForStatement or WhileStatement) and count(*//AssignmentOperator)=1 and */Statement [ ./Block/BlockStatement/Statement/StatementExpression/PrimaryExpression /PrimaryPrefix/Name/../../PrimarySuffix/Expression [(PrimaryExpression or AdditiveExpression) and count (.//PrimaryPrefix/Name)=1]//PrimaryPrefix/Name/@Image and ./Block/BlockStatement/Statement/StatementExpression/Expression/PrimaryExpression /PrimaryPrefix/Name/../../PrimarySuffix[count (..//PrimarySuffix)=1]/Expression[(PrimaryExpression or AdditiveExpression) and count(.//PrimaryPrefix/Name)=1] //PrimaryPrefix/Name/@Image ]]
Here's an example of code that would trigger this rule:
public class Test { public void bar() { int[] a = new int[10]; int[] b = new int[10]; for (int i=0;i<10;i++) { b[i]=a[i]; } } } // this will trigger the rule for (int i=0;i<10;i++) { b[i]=a[c[i]]; } } }