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

perf(mangling): optimized the processing of initialisms #79

Merged
merged 1 commit into from
Jan 22, 2024

Conversation

fredbi
Copy link
Member

@fredbi fredbi commented Jan 11, 2024

This PR significantly improves the performance of name-mangling
utilities (e.g. ToGoName, etc).

The need for this occurred while benchmarking go-swagger's CI suite:
surprisingly, the topmost allocator was swag.ToGoName.

It is the result of a dozen successive optimization passes driven
by profiling.

These functions now execute ~10x faster and need 100 times less
memory allocations. See BENCHMARK.md

Optimization techniques used to reduce allocations:

  • pointer -> value (everything was pointers: now everything is values)
  • interface -> struct with a Kind field
  • closure -> func
  • string to []byte: use unsafe conversion
  • string concatenation -> use bytes.Buffer (recyclable, unlike
    strings.Builder)
  • static values converted over and over again: pre-bake the conversions
  • var x []T -> make([]T, 0, heuristic size)
  • temporarily allocated values -> use pools to recycle previously
    allocated data items

Optimization techniques used to reduce CPU:

  • read Unicode rune -> short-circuit for single byte runes
  • map lookup -> func with switch statement
  • for i, v := range -> for i := range (minor impact)

Signed-off-by: Frédéric BIDON fredbi@yahoo.com

@fredbi fredbi changed the title Perf/perf initialisms perf(mangling): optimized the processing of initialisms Jan 11, 2024
Copy link

codecov bot commented Jan 11, 2024

Codecov Report

Attention: 7 lines in your changes are missing coverage. Please review.

Comparison is base (b3e7a53) 85.45% compared to head (0ba0453) 86.91%.

❗ Current head 0ba0453 differs from pull request most recent head 5904b43. Consider uploading reports for the commit 5904b43 to get more accurate results

Files Patch % Lines
util.go 89.85% 6 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #79      +/-   ##
==========================================
+ Coverage   85.45%   86.91%   +1.45%     
==========================================
  Files          12       13       +1     
  Lines        1609     1842     +233     
==========================================
+ Hits         1375     1601     +226     
- Misses        202      208       +6     
- Partials       32       33       +1     
Flag Coverage Δ
oldstable 86.91% <98.33%> (+1.45%) ⬆️
stable 86.91% <98.33%> (+1.45%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@fredbi
Copy link
Member Author

fredbi commented Jan 11, 2024

integration test w/ go-swagger: go-swagger/go-swagger#3060

This PR significantly improves the performance of name mangling
utilities (e.g. ToGoName, etc).

The need for this occured while benchmarking go-swagger's CI suite:
surprisingly, the topmost allocator was swag.ToGoName.

It is the result of a dozen successive optimization passes driven
by profiling.

These functions now execute ~10x faster and need 100 times less
memory allocations. See BENCHMARK.md

Optimization techniques used to reduce allocations:
* pointer -> value (everything was pointers: now everything is values)
* interface -> struct with a Kind field
* closure -> func
* string to []byte: use unsafe conversion
* string concatenation -> use bytes.Buffer (recyclable, unlike
strings.Builder)
* static values converted over and over again: pre-bake the conversions
* var x []T  -> make([]T, 0, heuristic size)
* temporarily allocated values -> use pool to recycle previously
allocated data items

Optimization techniques used to reduce CPU:
* read unicode rune -> short-circuit for single byte runes
* map lookup -> func with switch statement
* for i, v := range -> for i := range (minor impact)

Signed-off-by: Frédéric BIDON <fredbi@yahoo.com>
@fredbi fredbi marked this pull request as ready for review January 20, 2024 07:37
@fredbi
Copy link
Member Author

fredbi commented Jan 20, 2024

I've been testing this over the week with go-openapi/analysis, go-openapi/validate and go-swagger.
The reduction in generated garbage is quite significant, but not enough to translate in noticeable timings improvements.
Consider this PR as a supplement to the effort started with go-swagger/go-swagger#3063 and another important forthcoming PR on go-openapi/validate, as joint efforts to contribute to go-swagger/go-swagger#2649

@fredbi fredbi merged commit 01194a0 into go-openapi:master Jan 22, 2024
8 checks passed
@fredbi fredbi deleted the perf/perf-initialisms branch January 22, 2024 07:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants