Skip to content

Commit

Permalink
green-code-initiative#63 - doc: Fixes misleading documentation and re…
Browse files Browse the repository at this point in the history
  • Loading branch information
jycr committed Mar 21, 2023
1 parent 664fe07 commit bb8f4df
Show file tree
Hide file tree
Showing 34 changed files with 914 additions and 1,221 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
@Rule(
key = "EC4",
name = "Developpement",
description = "<p>Prefer local variables to globals</p>",
description = "Prefer local variables to globals",
priority = Priority.MINOR,
tags = {"bug"}
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
<p>Using Spring repository in loop induced unnecessary calculation by the cpu so unless energy consumption.</p>
<h2>Noncompliant Code Example</h2>
<pre>
private final List&lt;Integer&gt; ids = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
<p>The use of Spring repository in a loop induces unnecessary calculations by the CPU and therefore superfluous energy consumption.</p>

List&lt;Employee&gt; employees = new ArrayList&lt;&gt;();
<h2>Example of non-compliant code</h2>
<pre>
private final List&lt;Integer&gt; ids = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

for (Integer id: ids) {
Optional&lt;Employee&gt; employee = employeeRepository.findById(id); // Noncompliant
if (employee.isPresent()) {
employees.add(employee.get());
}
}
List&lt;Employee&gt; employees = new ArrayList&lt;&gt;();

for (Integer id: ids) {
Optional&lt;Employee&gt; employee = employeeRepository.findById(id); // Noncompliant
if (employee.isPresent()) {
employees.add(employee.get());
}
}
</pre>

<h2>Compliant Solution</h2>
<pre>
private final List&lt;Integer&gt; ids = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List&lt;Employee&gt; employees = employeeRepository.findAllById(ids);
private final List&lt;Integer&gt; ids = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List&lt;Employee&gt; employees = employeeRepository.findAllById(ids);
</pre>
Original file line number Diff line number Diff line change
@@ -1,31 +1,34 @@
<p>If we are using too many conditional if-else statements it will impact performance since JVM will have to compare the conditions. We can think of using a switch statement instead of multiple if-else if possible. Switch statement has a performance advantage over if – else.</p>
<p>
If we are using too many conditional <code>if</code>-<code>else</code> statements it will impact performance since JVM will have to compare the conditions.
We can think of using a switch statement instead of multiple <code>if</code>-<code>else</code> if possible.
Switch statement has a performance advantage over <code>if</code>-<code>else</code>.
</p>

<h2>Non-compliant Code Example</h2>
<h2>Example of non-compliant code</h2>
<pre>
int index = 1;
int nb = 2;

if (nb > index) {
nb = nb + index;
} else {
nb = nb - 1;
}
if (nb != index + 1) {
nb = nb + index;
} else {
nb = nb - 1;
}

int index = 1;
int nb = 2;

if (nb > index) {
nb = nb + index;
} else {
nb = nb - 1;
}
if (nb != index + 1) {
nb = nb + index;
} else {
nb = nb - 1;
}
</pre>

<h2>Compliant Code Example</h2>
<pre>
int index = 1;
int nb = 2;
int index = 1;
int nb = 2;

if (nb > index) {
nb = nb + index;
} else {
nb = nb - 1;
}
if (nb > index) {
nb = nb + index;
} else {
nb = nb - 1;
}
</pre>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<p>Using System.arraycopy to copy arrays</p>
<p>Using <code>System.arraycopy</code> to copy arrays</p>
<p>
Programs spend most of the time in loops. These can be resource consuming, especially when they integrate heavy processing (IO access). Moreover, the size of the data and processing inside the loops will not allow full use of hardware mechanisms such as the cache or compiler optimization mechanisms.<br />
For example, an array copy is potentially a non-performance source if it is poorly designed. Indeed, the use of a single copy loop can be twice as consuming as dedicated methods.<br />
Expand All @@ -7,18 +7,20 @@
We can also use <code>copyOf</code> or <code>clone</code> that are slightly less efficient.<br />
The looping method will be outlawed.
</p>
<h2>Noncompliant Code Example</h2>

<h2>Example of non-compliant code</h2>
<pre>
int len = array.length;
boolean[] copy = new boolean[array.length];
for (int i = 0; i < len; i++) {
copy[i] = array[i]; // Noncompliant
}
return copy;
int len = array.length;
boolean[] copy = new boolean[array.length];
for (int i = 0; i < len; i++) {
copy[i] = array[i]; // Noncompliant
}
return copy;
</pre>

<h2>Compliant Solution</h2>
<pre>
int[] copy = new int[array.length];
System.arraycopy(array, 0, copy, 0, array.length);
return copy;
int[] copy = new int[array.length];
System.arraycopy(array, 0, copy, 0, array.length);
return copy;
</pre>
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
<p>Optimize read file exception</p>
<h2>Noncompliant Code Example</h2>
<pre>
public void readPreferences(String filename) {
//...
InputStream in = null;
try {
in = new FileInputStream(filename);
} catch (FileNotFoundException e) {
logger.log(e);
}
in.read(...);
//...
}

<h2>Example of non-compliant code</h2>
<pre>
public void readPreferences(String filename) {
//...
InputStream in = null;
try {
in = new FileInputStream(filename);
} catch (FileNotFoundException e) {
logger.log(e);
}
in.read(...);
//...
}
</pre>

<h2>Compliant Solution</h2>
<pre>
public void readPreferences(String filename)
throws IllegalArgumentException,
FileNotFoundException, IOException {
if (filename == null) {
throw new IllegalArgumentException ("filename is null");
} //if
//...
InputStream in = new FileInputStream(filename);
//...
}
public void readPreferences(String filename) throws IllegalArgumentException, FileNotFoundException, IOException {
if (filename == null) {
throw new IllegalArgumentException ("filename is null");
}
//...
InputStream in = new FileInputStream(filename);
//...
}
</pre>
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
<p>When iterating over any collection, fetch the size of the collection in advance to avoid fetching it on each iteration, this saves CPU cycles, and therefore consumes less power. The example provided below illustrates what should be avoided.</p>
<h2>Noncompliant Code Example</h2>
<pre>
List&lt;String&gt; objList = getData();

for (int i = 0; i < objList.size(); i++) { // Noncompliant
// execute code
}
<h2>Example of non-compliant code</h2>
<pre>
List&lt;String&gt; objList = getData();

for (int i = 0; i < objList.size(); i++) { // Noncompliant
// execute code
}
</pre>

<h2>Compliant Solution</h2>
<pre>
List&lt;String&gt; objList = getData();
List&lt;String&gt; objList = getData();

int size = objList.size();
for (int i = 0; i < size; i++) {
// execute code
}
int size = objList.size();
for (int i = 0; i < size; i++) {
// execute code
}
</pre>
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
<p>
If you know in advance how many characters would be appended, initialize builder/buffer with the appropriate size.
They will thus never have to be resized, It saves CPU cycles so unless energy consumption.
If you know in advance how many characters would be appended, initialize builder/buffer with the appropriate size.
They will thus never have to be resized.
This saves CPU cycles and therefore consumes less energy.
</p>
<h2>Noncompliant Code Example</h2>

<h2>Example of non-compliant code</h2>
<pre>
StringBuilder sb = new StringBuilder(); // Noncompliant
for (int i = 0; i < 100; i++) {
sb.append(...);
}
StringBuilder sb = new StringBuilder(); // Noncompliant
for (int i = 0; i < 100; i++) {
sb.append(...);
}
</pre>

<h2>Compliant Solution</h2>
<pre>
StringBuilder sb = new StringBuilder(100);
for (int i = 0; i < 100; i++) {
sb.append(...);
}
StringBuilder sb = new StringBuilder(100);
for (int i = 0; i < 100; i++) {
sb.append(...);
}
</pre>
Original file line number Diff line number Diff line change
@@ -1,26 +1,38 @@
<p>Prefer local variables as parameters</p>

<p>When calling a global variable, the interpretation engine must check that it exists in all scopes, that it has a value, etc. Passing global variables as arguments gives them the status of local variables inside the function, which saves computation time (CPU cycles).</p>

<h2>CASE 1 (Avoid as much as possible)</h2>
<p>
Prefer local variables as parameters
</p>
<p>When calling a global variable, the interpretation engine must check that it exists in all the scopes, that it has a value, etc. Passing global variables as arguments gives them the statut of local variables inside the function, thus saving computing time (CPU cycles).
You are back on the service code.
You see that <code>func1()</code> uses <code>globalVariabl1</code>.
Alright, but what's its value now? How does it change?
Who mutates the <code>globalVariabl1</code> before it gets to this function?
What was the sequence of all these mutations?
You would have no idea.
It will be quite difficult to understand all this.
</p>

<h2>CASE 2 (Recommended)</h2>
<p>
CASE 1 (Avoid as possible):<br>
You are back on the service code. You see that the func1() uses globalVariabl1. Okay, but whats its value by now ? How does it change ? Who mutates the globalVariabl1 before it comes to this function ? What have been the sequence of all these mutations ? You would have no idea. It will be quite difficult to figure all this out.
<br>
CASE 2 (Recommended):<br>
You are back to you code, and see that the func0() fetches something and then passes it to func1(param1) as a parameter. You clearly know what the data is, how does it gets here.
</p><br>
<p>example:<br>
var aGlobal = new String('Hello');<br>
function globalLength(){<br>
length = aGlobal.length;<br>
console.log(length);<br>
}<br>
globalLength();<br>
<br>
var aGlobal = new String('Hello');<br>
function someVarLength(str){<br>
length = str.length;<br>
console.log(length);<br>
}<br>
somVarLength(aGlobal);</p>
You are back to your code and see that <code>func0()</code> is getting something and then passing it to <code>func1(param1)</code> as a parameter.
You clearly know what the data is, and how it gets here.
</p>

<p>Example:</p>

<pre>
var aGlobal = new String('Hello');
function globalLength() {
length = aGlobal.length;
console.log(length);
}
globalLength();

var aGlobal = new String('Hello');
function someVarLength(str) {
length = str.length;
console.log(length);
}
somVarLength(aGlobal);
</pre>
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
<p>Use PreparedStatement instead of Statement, that's because SQL will validate the query only once, whereas if you just use a statement it will validate the query each time.
This induced unnecessary calculation by the CPU so unless energy consumption.</p>
<h2>Noncompliant Code Example</h2>
<p>Use <code>PreparedStatement</code> instead of <code>Statement</code>, because SQL will only commit the query once, whereas if you used only one statement, it would commit the query every time and thus induce unnecessary calculations by the CPU and therefore superfluous energy consumption.</p>

<h2>Example of non-compliant code</h2>
<pre>
public void select() {
Statement statement = connection.createStatement();
statement.executeUpdate("INSERT INTO persons(id, name) VALUES(2, 'Toto')"); // Noncompliant
}
public void select() {
Statement statement = connection.createStatement();
statement.executeUpdate("INSERT INTO persons(id, name) VALUES(2, 'Toto')"); // Noncompliant
}
</pre>

<h2>Compliant Solution</h2>
<pre>
public void select() {
PreparedStatement statement = connection.prepareStatement(INSERT INTO persons(id, name) VALUES(?, ?));
public void select() {
PreparedStatement statement = connection.prepareStatement("INSERT INTO persons(id, name) VALUES(?, ?)");

statement.setInt(1, 2);
statement.setString(2, "Toto");
statement.executeQuery();
}
statement.setInt(1, 2);
statement.setString(2, "Toto");
statement.executeQuery();
}
</pre>
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
<p>Using List instead of Arrays with Foreach save CPU cycles calculations and RAM consumption.</p>
<h2>Noncompliant Code Example</h2>
<pre>
private final Integer[] intArray = new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
<p>Using List instead of Arrays with Foreach will save CPU cycles calculations and RAM consumption.</p>

for (Integer i : intArray) {
...
}
<h2>Example of non-compliant code</h2>
<pre>
private final Integer[] intArray = new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

for (Integer i : intArray) {
// ...
}
</pre>

<h2>Compliant Solution</h2>
<pre>
private final List&lt;Integer&gt; intList = Arrays.asList(new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
private final List&lt;Integer&gt; intList = Arrays.asList(new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });

for (Integer i : intList) {
...
}
for (Integer i : intList) {
// ...
}
</pre>
Loading

0 comments on commit bb8f4df

Please sign in to comment.