Skip to content
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

Optimise iteration and lookups #3

Merged
merged 14 commits into from
Apr 10, 2024
Merged

Optimise iteration and lookups #3

merged 14 commits into from
Apr 10, 2024

Conversation

mikee47
Copy link
Owner

@mikee47 mikee47 commented Apr 10, 2024

This PR improves performance of object iteration and indexing.

For example, calling indexOf on an Array<uint32_t> object results in repeated calls to the data() method.
Further, the C++ iterator implementation does the same.

A new speed test module has been added to evaulate performance. This uses some moderately large test objects and evaluates how long it takes to iterate through them using three methods:

  1. regular for(unsigned i=0; i<array.count(); ++i) loop
  2. C++ iterator for(auto: array)
  3. Using the indexOf method

Array has 1000 elements.
Vector has 367 elements, referencing 3208 bytes of string data.
Map<int, String> has 367 elements.

These are the results, in microseconds, on an esp8266:

Operation Current With this PR
Array for-loop 1603 1611
Array iterator 1326 403
Array.indexOf 1303 425
Vector for-loop 800 721
Vector iterator 774 402
Vector indexOf(const char*) 6634 969
Vector indexOf(String) 849 476
Map<int, String> for-loop 1042 1085
Map<int, String> iterator 891 577
Map<int, String> indexOf 189 189
Map<int, String> lookup 168 168

Optimise iteration and indexOf operation

The regular [] operator and valueAt methods include range checks which are costly inside a loop.
Adding unsafe methods skips these checks.

Improve Vector search for char argument*

The indexOf method has been specialised for char* arguments so that strlen() only needs to be called once. Previously it was called on every loop iteration.

Provide base == operator which does binary comparison

This allows easy searching by value (object content).

Rationalise string comparison methods

FlashStrings have three equals overloads for char*, String and FlashString arguments.
We also require three equalsignorecase equivalents and appropriate operator== implementations.

By adding an ignoreCase parameter to all three equals methods we can simplify code.

Other improvements

  • Use const references instead of copy
  • Move copy/invalidate operations to constructors
  • Use constexpr where possible for method return values
  • Move printElement(Print, char) specialization into source file
  • Move read method out of header
  • Add github workflow
  • Put strings in flash

@mikee47 mikee47 merged commit a452662 into develop Apr 10, 2024
23 of 24 checks passed
@mikee47 mikee47 deleted the feature/optimise branch April 10, 2024 11:35
@mikee47
Copy link
Owner Author

mikee47 commented Apr 10, 2024

Note: Squash commit deleted in favour of branch merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant