-
-
Notifications
You must be signed in to change notification settings - Fork 58
⚡ Bolt: Optimize random string generation with String.fromCharCodes and cached Random.secure() #2202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
⚡ Bolt: Optimize random string generation with String.fromCharCodes and cached Random.secure() #2202
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +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<int>` 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. |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -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) { | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The local variable
Suggested change
References
|
||||||
| return rand.nextInt(33) + 89; | ||||||
| return _secureRandom.nextInt(33) + 89; | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The magic numbers const _charRange = 33;
const _charStartCode = 89; // ASCII for 'Y'
...
return _secureRandom.nextInt(_charRange) + _charStartCode; |
||||||
| }); | ||||||
|
|
||||||
| 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<int>.generate( | ||||||
| length, | ||||||
| (_) => _idCharCodes[_secureRandom.nextInt(_idCharCodes.length)], | ||||||
| ); | ||||||
| return String.fromCharCodes(codes); | ||||||
| } | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This character set is also defined in
lib/abgabe/abgabe_client_lib/lib/src/models/auto_id_generator.dartandlib/sharezone_utils/lib/src/random_string/random_string.dart. To improve maintainability and prevent inconsistencies, it would be best to define this alphabet as a single shared constant. If package dependencies prevent sharing, please ensure the string values are identical across all files. Note that the character order in this file is different from the others.