Skip to content

Commit 51d9d62

Browse files
GCI104 StringConcatenation #Python #DLG #RulesSpecifications
Co-authored-by: DataLabGroupe-CreditAgricole <[email protected]>
1 parent a5c2c8e commit 51d9d62

File tree

5 files changed

+88
-0
lines changed

5 files changed

+88
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
- Add a rule on Python String Concatenation
13+
1214
### Changed
1315

1416
- Correction of various typos in rules documentations

RULES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ Some are applicable for different technologies.
7171
| GCI92 | Use string.Length instead of comparison with empty string | Comparing a string to an empty string is unnecessary and can be replaced by a call to `string.Length` which is more performant and more readable. | | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 || 🚫 |
7272
| GCI93 | Return `Task` directly | Consider returning a `Task` directly instead of a single `await` | ||||||||
7373
| GCI94 | Use orElseGet instead of orElse | Parameter of orElse() is evaluated, even when having a non-empty Optional. Supplier method of orElseGet passed as an argument is only executed when an Optional value isn’t present. Therefore, using orElseGet() will save computing time. | [Optimized use of Java Optional Else](https://github.com/green-code-initiative/creedengo-challenge/issues/77) || 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 |
74+
| GCI105 | Python String Concatenation | Python String Concatenation - Use Join Instead or f-Strings instead of += | | 🚫 | 🚫 | 🚫 | 🚀 | 🚫 | 🚫 | 🚫 |
7475
| GCI203 | Detect unoptimized file formats | When it is possible, to use svg format image over other image format | | 🚧 | 🚀 | 🚀 || 🚀 | 🚀 | 🚫 |
7576
| GCI404 | Avoid list comprehension in iterations | Use generator comprehension instead of list comprehension in for loop declaration | | 🚫 | 🚫 | 🚫 || 🚫 | 🚫 | 🚫 |
7677
| GCI522 | Sobriety: Brightness Override | To avoid draining the battery, iOS and Android devices adapt the brightness of the screen depending on the environment light. | | 🚫 | 🚫 || 🚫 | 🚫 | 🚫 | 🚫 |

src/main/rules/GCI105/GCI105.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"title": "Python String Concatenation - Use Join Instead or f-Strings instead of +=",
3+
"type": "CODE_SMELL",
4+
"status": "ready",
5+
"remediation": {
6+
"func": "Constant\/Issue",
7+
"constantCost": "1min"
8+
},
9+
"tags": [
10+
"creedengo",
11+
"eco-design",
12+
"performance",
13+
"python",
14+
"string"
15+
],
16+
"defaultSeverity": "Minor"
17+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
With Python, concatenating strings with `+=` in a loop creates many intermediate strings, leading to high memory usage and performance degradation. Prefer using f-strings (formatted string literals) or `str.join()` for better performance and lower environmental impact.
2+
3+
== Non Compliant Code Example
4+
5+
[source,python]
6+
----
7+
city = "New York"
8+
street = "5th Avenue"
9+
zip_code = "10001"
10+
address = ""
11+
address += city + ", " + street + zip_code # Noncompliant: inefficient string concatenation
12+
----
13+
14+
In this example, the `+=` operation creates a new string object for each concatenation. When done repeatedly (e.g., in loops), this leads to excessive memory allocations and slower performance.
15+
16+
== Compliant Solution
17+
18+
[source,python]
19+
----
20+
# Using f-string for readability and performance
21+
city = "New York"
22+
street = "5th Avenue"
23+
address = f"{city}, {street}"
24+
# or using str.join() for multiple string concatenations
25+
parts = ["New York", "5th Avenue", "10001"]
26+
address = ", ".join(parts)
27+
----
28+
29+
These approaches avoid the repeated creation of new string objects. `str.join()` builds the final string in a single operation, and f-strings are compiled into efficient bytecode.
30+
31+
== Relevance Analysis
32+
33+
This rule applies to any Python application performing repeated or large-scale string concatenation (e.g., log generation, data serialization, HTML template generation).
34+
35+
=== Configuration
36+
37+
* Processor: Intel(R) Core(TM) Ultra 5 135U, 2100 MHz, 12 cores, 14 logical processors
38+
* RAM: 16 GB
39+
* CO2 Emissions Measurement: Using CodeCarbon
40+
41+
=== Context
42+
43+
Two string-building techniques were benchmarked:
44+
- **Non-compliant:** `+=` string concatenation in a loop
45+
- **Compliant:** `str.join()` or f-string formatting
46+
47+
Metrics assessed:
48+
- Execution time
49+
- Carbon emissions
50+
51+
=== Impact Analysis
52+
53+
image::concat.png[]
54+
55+
- *CO₂ Emissions:* Reduced by over **10×** when using `str.join()` instead of `+=`
56+
- *Energy Efficiency:* Significantly improved due to lower memory allocations and faster execution
57+
58+
These results demonstrate that even small code patterns, like string concatenation, can have a measurable impact when scaled in production environments.
59+
60+
== Conclusion
61+
62+
Replacing `+=` in string concatenation with `f-strings` or `str.join()`:
63+
- Reduces memory overhead
64+
- Improves runtime performance
65+
- Decreases CO₂ emissions
66+
67+
== References
68+
- https://wiki.python.org/moin/PythonSpeed/PerformanceTips
21.6 KB
Loading

0 commit comments

Comments
 (0)