From 60321a63c9d371a43e696860db0c9011ee1cddb8 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 1 Mar 2026 12:27:10 +0000 Subject: [PATCH 1/2] Optimize random string generation avoiding O(N^2) concat Replaced O(N^2) string concatenation using `+=` inside loops with O(N) `String.fromCharCodes` and `List.generate`. Reused cached instances of `Random.secure()` instead of instantiating `Random()` on every call to improve performance and guarantee cryptographic security for IDs. Co-authored-by: nilsreichardt <24459435+nilsreichardt@users.noreply.github.com> --- .jules/bolt.md | 3 +++ .../lib/src/models/auto_id_generator.dart | 17 +++++++-------- .../lib/src/ids/src/id.dart | 19 +++++++++-------- .../lib/src/random_string/random_string.dart | 21 ++++++++++--------- 4 files changed, 32 insertions(+), 28 deletions(-) create mode 100644 .jules/bolt.md diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 000000000..00ca2bf2a --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2024-03-01 - [Fast String Concatenation and Secure Random] +**Learning:** String concatenation using `+=` inside loops is very slow for large iterations (O(N^2)). Using `StringBuffer` or allocating a `List` and using `String.fromCharCodes` is significantly faster (O(N)). Additionally, `Random.secure()` has a slight performance overhead but is essential for IDs to prevent predictability. Caching `Random.secure()` instances avoids initialization overhead. +**Action:** Replace `+=` string concatenation with `String.fromCharCodes` inside random string generators. Cache `Random.secure()` to save instantiation time. diff --git a/lib/abgabe/abgabe_client_lib/lib/src/models/auto_id_generator.dart b/lib/abgabe/abgabe_client_lib/lib/src/models/auto_id_generator.dart index 86c44fb09..ce3df0a63 100644 --- a/lib/abgabe/abgabe_client_lib/lib/src/models/auto_id_generator.dart +++ b/lib/abgabe/abgabe_client_lib/lib/src/models/auto_id_generator.dart @@ -16,17 +16,16 @@ class AutoIdGenerator { static const String alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - static final Random _random = Random(); + static final Random _secureRandom = Random.secure(); + static final _alphabetCodeUnits = alphabet.codeUnits; /// Automatically Generates a random new Id static String autoId() { - final stringBuffer = StringBuffer(); - const maxRandom = alphabet.length; - - for (var i = 0; i < idLength; ++i) { - stringBuffer.write(alphabet[_random.nextInt(maxRandom)]); - } - - return stringBuffer.toString(); + final codes = List.generate( + idLength, + (_) => + _alphabetCodeUnits[_secureRandom.nextInt(_alphabetCodeUnits.length)], + ); + return String.fromCharCodes(codes); } } diff --git a/lib/common_domain_models/lib/src/ids/src/id.dart b/lib/common_domain_models/lib/src/ids/src/id.dart index 022a684c5..e08cb94ad 100644 --- a/lib/common_domain_models/lib/src/ids/src/id.dart +++ b/lib/common_domain_models/lib/src/ids/src/id.dart @@ -8,6 +8,10 @@ import 'dart:math'; +final _secureRandom = Random.secure(); +const _chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; +final _charCodes = _chars.codeUnits; + class Id { final String value; @@ -21,15 +25,12 @@ class Id { /// Generates a new random [Id] with the given [length] using characters /// from a-z, A-Z and 0-9. static Id generate({int length = 20, Random? random}) { - random ??= Random(); - const chars = - 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; - final id = - List.generate( - length, - (index) => chars[random!.nextInt(chars.length)], - ).join(); - return Id(id); + final rand = random ?? _secureRandom; + final codes = List.generate( + length, + (_) => _charCodes[rand.nextInt(_charCodes.length)], + ); + return Id(String.fromCharCodes(codes)); } @override diff --git a/lib/sharezone_utils/lib/src/random_string/random_string.dart b/lib/sharezone_utils/lib/src/random_string/random_string.dart index 2322868a4..1ebd9aca2 100644 --- a/lib/sharezone_utils/lib/src/random_string/random_string.dart +++ b/lib/sharezone_utils/lib/src/random_string/random_string.dart @@ -8,22 +8,23 @@ import 'dart:math'; +final _secureRandom = Random.secure(); +const _idChars = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; +final _idCharCodes = _idChars.codeUnits; + String randomString(int length) { - var rand = Random(); var codeUnits = List.generate(length, (index) { - return rand.nextInt(33) + 89; + return _secureRandom.nextInt(33) + 89; }); return String.fromCharCodes(codeUnits); } String randomIDString(int length) { - var rand = Random(); - const chars = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - String result = ""; - for (var i = 0; i < length; i++) { - result += chars[rand.nextInt(chars.length)]; - } - return result; + final codes = List.generate( + length, + (_) => _idCharCodes[_secureRandom.nextInt(_idCharCodes.length)], + ); + return String.fromCharCodes(codes); } From ea9a56c02193b538e5c882e40e3afb70529298dd Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 1 Mar 2026 12:31:22 +0000 Subject: [PATCH 2/2] Fix Prettier formatting for markdown file .jules/bolt.md Co-authored-by: nilsreichardt <24459435+nilsreichardt@users.noreply.github.com> --- .jules/bolt.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.jules/bolt.md b/.jules/bolt.md index 00ca2bf2a..a7592500e 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -1,3 +1,4 @@ ## 2024-03-01 - [Fast String Concatenation and Secure Random] + **Learning:** String concatenation using `+=` inside loops is very slow for large iterations (O(N^2)). Using `StringBuffer` or allocating a `List` and using `String.fromCharCodes` is significantly faster (O(N)). Additionally, `Random.secure()` has a slight performance overhead but is essential for IDs to prevent predictability. Caching `Random.secure()` instances avoids initialization overhead. **Action:** Replace `+=` string concatenation with `String.fromCharCodes` inside random string generators. Cache `Random.secure()` to save instantiation time.