[PR #331] [MERGED] fix: Fixes and performance improvements in utils package #869

Closed
opened 2025-10-09 16:58:47 +03:00 by OVERLORD · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/pocket-id/pocket-id/pull/331
Author: @ItalyPaleAle
Created: 3/14/2025
Status: Merged
Merged: 3/15/2025
Merged by: @kmendell

Base: mainHead: utils-fixes-perf


📝 Commits (6)

📊 Changes

6 files changed (+260 additions, -28 deletions)

View changed files

📝 .github/workflows/e2e-tests.yml (+23 -0)
📝 backend/internal/utils/file_util.go (+5 -3)
backend/internal/utils/file_util_test.go (+73 -0)
📝 backend/internal/utils/image/profile_picture.go (+1 -1)
📝 backend/internal/utils/string_util.go (+53 -24)
backend/internal/utils/string_util_test.go (+105 -0)

📄 Description

  1. Fixed: GetFileExtension panics if the input is an empty string
  2. Some major performance improvements in a few functions in string_util.go: GenerateRandomAlphanumericString, CapitalizeFirstLetter, CamelCaseToSnakeCase. In addition to being faster, in some cases a lot (see BenchmarkGenerateRandomAlphanumericString/128-12 where individual execution time is now 94% faster), there are a lot less allocations (and they are mostly constant and not increasing depending on input), which reduces the pressure on the GC

Behavior is unchanged, as confirmed by unit tests created before the refactorings.

Benchmark env

goos: darwin
goarch: arm64
pkg: github.com/pocket-id/pocket-id/backend/internal/utils
cpu: Apple M2 Pro

Before

BenchmarkGenerateRandomAlphanumericString

BenchmarkGenerateRandomAlphanumericString/8
BenchmarkGenerateRandomAlphanumericString/8-12  	 1193881	      1019 ns/op	     400 B/op	      26 allocs/op
BenchmarkGenerateRandomAlphanumericString/16
BenchmarkGenerateRandomAlphanumericString/16-12 	  589038	      2008 ns/op	     800 B/op	      50 allocs/op
BenchmarkGenerateRandomAlphanumericString/32
BenchmarkGenerateRandomAlphanumericString/32-12 	  300684	      3904 ns/op	    1600 B/op	      98 allocs/op
BenchmarkGenerateRandomAlphanumericString/64
BenchmarkGenerateRandomAlphanumericString/64-12 	  153901	      7766 ns/op	    3200 B/op	     194 allocs/op
BenchmarkGenerateRandomAlphanumericString/128
BenchmarkGenerateRandomAlphanumericString/128-12         	   76503	     15581 ns/op	    6400 B/op	     386 allocs/op

BenchmarkCapitalizeFirstLetter

BenchmarkCapitalizeFirstLetter/8
BenchmarkCapitalizeFirstLetter/8-12  	25683045	        46.23 ns/op	      16 B/op	       1 allocs/op
BenchmarkCapitalizeFirstLetter/16
BenchmarkCapitalizeFirstLetter/16-12 	15051484	        79.60 ns/op	      24 B/op	       1 allocs/op
BenchmarkCapitalizeFirstLetter/32
BenchmarkCapitalizeFirstLetter/32-12 	 6564974	       156.0 ns/op	      48 B/op	       1 allocs/op
BenchmarkCapitalizeFirstLetter/64
BenchmarkCapitalizeFirstLetter/64-12 	 3047734	       369.2 ns/op	     336 B/op	       2 allocs/op
BenchmarkCapitalizeFirstLetter/128
BenchmarkCapitalizeFirstLetter/128-12         	 1637955	       713.2 ns/op	     656 B/op	       2 allocs/op

BenchmarkCamelCaseToSnakeCase

BenchmarkCamelCaseToSnakeCase/simpleCase
BenchmarkCamelCaseToSnakeCase/simpleCase-12         	 7900533	       140.2 ns/op	     136 B/op	       5 allocs/op
BenchmarkCamelCaseToSnakeCase/PascalCase
BenchmarkCamelCaseToSnakeCase/PascalCase-12         	 7169013	       139.8 ns/op	     136 B/op	       5 allocs/op
BenchmarkCamelCaseToSnakeCase/ThisIsALongerStringWithMultipleWords
BenchmarkCamelCaseToSnakeCase/ThisIsALongerStringWithMultipleWords-12         	 2767956	       402.4 ns/op	     552 B/op	       7 allocs/op
BenchmarkCamelCaseToSnakeCase/HTTPRequestHandler
BenchmarkCamelCaseToSnakeCase/HTTPRequestHandler-12                           	 4547570	       232.3 ns/op	     280 B/op	       6 allocs/op
BenchmarkCamelCaseToSnakeCase/OAuth2ClientID
BenchmarkCamelCaseToSnakeCase/OAuth2ClientID-12                               	 5208450	       202.9 ns/op	     272 B/op	       6 allocs/op

After

BenchmarkGenerateRandomAlphanumericString

BenchmarkGenerateRandomAlphanumericString/8
BenchmarkGenerateRandomAlphanumericString/8-12  	10384836	       114.7 ns/op	      24 B/op	       2 allocs/op
BenchmarkGenerateRandomAlphanumericString/16
BenchmarkGenerateRandomAlphanumericString/16-12 	 3644259	       303.2 ns/op	      40 B/op	       2 allocs/op
BenchmarkGenerateRandomAlphanumericString/32
BenchmarkGenerateRandomAlphanumericString/32-12 	 3281170	       336.1 ns/op	      80 B/op	       2 allocs/op
BenchmarkGenerateRandomAlphanumericString/64
BenchmarkGenerateRandomAlphanumericString/64-12 	 2738896	       410.4 ns/op	     160 B/op	       2 allocs/op
BenchmarkGenerateRandomAlphanumericString/128
BenchmarkGenerateRandomAlphanumericString/128-12         	 1993492	       572.8 ns/op	     304 B/op	       2 allocs/op

BenchmarkCapitalizeFirstLetter

BenchmarkCapitalizeFirstLetter/8
BenchmarkCapitalizeFirstLetter/8-12  	31061524	        39.14 ns/op	       8 B/op	       1 allocs/op
BenchmarkCapitalizeFirstLetter/16
BenchmarkCapitalizeFirstLetter/16-12 	18976692	        62.44 ns/op	      16 B/op	       1 allocs/op
BenchmarkCapitalizeFirstLetter/32
BenchmarkCapitalizeFirstLetter/32-12 	11386884	       105.3 ns/op	      32 B/op	       1 allocs/op
BenchmarkCapitalizeFirstLetter/64
BenchmarkCapitalizeFirstLetter/64-12 	 5534036	       191.9 ns/op	      64 B/op	       1 allocs/op
BenchmarkCapitalizeFirstLetter/128
BenchmarkCapitalizeFirstLetter/128-12         	 3081794	       364.9 ns/op	     128 B/op	       1 allocs/op

BenchmarkCamelCaseToSnakeCase

BenchmarkCamelCaseToSnakeCase/simpleCase
BenchmarkCamelCaseToSnakeCase/simpleCase-12         	24040098	        48.83 ns/op	      16 B/op	       1 allocs/op
BenchmarkCamelCaseToSnakeCase/PascalCase
BenchmarkCamelCaseToSnakeCase/PascalCase-12         	23784078	        49.48 ns/op	      16 B/op	       1 allocs/op
BenchmarkCamelCaseToSnakeCase/ThisIsALongerStringWithMultipleWords
BenchmarkCamelCaseToSnakeCase/ThisIsALongerStringWithMultipleWords-12         	 6214612	       164.2 ns/op	      48 B/op	       1 allocs/op
BenchmarkCamelCaseToSnakeCase/HTTPRequestHandler
BenchmarkCamelCaseToSnakeCase/HTTPRequestHandler-12                           	14924120	        80.26 ns/op	      24 B/op	       1 allocs/op
BenchmarkCamelCaseToSnakeCase/OAuth2ClientID
BenchmarkCamelCaseToSnakeCase/OAuth2ClientID-12                               	15093292	        79.50 ns/op	      48 B/op	       2 allocs/op

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/pocket-id/pocket-id/pull/331 **Author:** [@ItalyPaleAle](https://github.com/ItalyPaleAle) **Created:** 3/14/2025 **Status:** ✅ Merged **Merged:** 3/15/2025 **Merged by:** [@kmendell](https://github.com/kmendell) **Base:** `main` ← **Head:** `utils-fixes-perf` --- ### 📝 Commits (6) - [`95efaad`](https://github.com/pocket-id/pocket-id/commit/95efaadc50fb9216c3a857cc4aa9bf61bfcd662e) fix: Fixes and performance improvements in utils package - [`8e78301`](https://github.com/pocket-id/pocket-id/commit/8e7830135ee53d2cb7ea3486dc4eeb5649cc5459) Merge branch 'main' into utils-fixes-perf - [`874c75d`](https://github.com/pocket-id/pocket-id/commit/874c75d749812641bf6f71cc580225c9aef494a0) Remove benchmarks - [`29a8edc`](https://github.com/pocket-id/pocket-id/commit/29a8edc236fbd71ce891712522820ef6de0b9ee5) Merge branch 'main' of https://github.com/pocket-id/pocket-id into utils-fixes-perf - [`7229b04`](https://github.com/pocket-id/pocket-id/commit/7229b04d2679062982482220a6746da6de7fd0a6) Run unit tests during CI - [`c5373be`](https://github.com/pocket-id/pocket-id/commit/c5373bef1a631ebd98ec6a7d92c094d187f1d411) Fix CI ### 📊 Changes **6 files changed** (+260 additions, -28 deletions) <details> <summary>View changed files</summary> 📝 `.github/workflows/e2e-tests.yml` (+23 -0) 📝 `backend/internal/utils/file_util.go` (+5 -3) ➕ `backend/internal/utils/file_util_test.go` (+73 -0) 📝 `backend/internal/utils/image/profile_picture.go` (+1 -1) 📝 `backend/internal/utils/string_util.go` (+53 -24) ➕ `backend/internal/utils/string_util_test.go` (+105 -0) </details> ### 📄 Description 1. Fixed: `GetFileExtension` panics if the input is an empty string 2. Some major performance improvements in a few functions in `string_util.go`: `GenerateRandomAlphanumericString`, `CapitalizeFirstLetter`, `CamelCaseToSnakeCase`. In addition to being faster, in some cases a lot (see `BenchmarkGenerateRandomAlphanumericString/128-12` where individual execution time is now 94% faster), there are a lot less allocations (and they are mostly constant and not increasing depending on input), which reduces the pressure on the GC Behavior is unchanged, as confirmed by unit tests created before the refactorings. ## Benchmark env goos: darwin goarch: arm64 pkg: github.com/pocket-id/pocket-id/backend/internal/utils cpu: Apple M2 Pro ## Before ### BenchmarkGenerateRandomAlphanumericString ``` BenchmarkGenerateRandomAlphanumericString/8 BenchmarkGenerateRandomAlphanumericString/8-12 1193881 1019 ns/op 400 B/op 26 allocs/op BenchmarkGenerateRandomAlphanumericString/16 BenchmarkGenerateRandomAlphanumericString/16-12 589038 2008 ns/op 800 B/op 50 allocs/op BenchmarkGenerateRandomAlphanumericString/32 BenchmarkGenerateRandomAlphanumericString/32-12 300684 3904 ns/op 1600 B/op 98 allocs/op BenchmarkGenerateRandomAlphanumericString/64 BenchmarkGenerateRandomAlphanumericString/64-12 153901 7766 ns/op 3200 B/op 194 allocs/op BenchmarkGenerateRandomAlphanumericString/128 BenchmarkGenerateRandomAlphanumericString/128-12 76503 15581 ns/op 6400 B/op 386 allocs/op ``` ### BenchmarkCapitalizeFirstLetter ``` BenchmarkCapitalizeFirstLetter/8 BenchmarkCapitalizeFirstLetter/8-12 25683045 46.23 ns/op 16 B/op 1 allocs/op BenchmarkCapitalizeFirstLetter/16 BenchmarkCapitalizeFirstLetter/16-12 15051484 79.60 ns/op 24 B/op 1 allocs/op BenchmarkCapitalizeFirstLetter/32 BenchmarkCapitalizeFirstLetter/32-12 6564974 156.0 ns/op 48 B/op 1 allocs/op BenchmarkCapitalizeFirstLetter/64 BenchmarkCapitalizeFirstLetter/64-12 3047734 369.2 ns/op 336 B/op 2 allocs/op BenchmarkCapitalizeFirstLetter/128 BenchmarkCapitalizeFirstLetter/128-12 1637955 713.2 ns/op 656 B/op 2 allocs/op ``` ### BenchmarkCamelCaseToSnakeCase ``` BenchmarkCamelCaseToSnakeCase/simpleCase BenchmarkCamelCaseToSnakeCase/simpleCase-12 7900533 140.2 ns/op 136 B/op 5 allocs/op BenchmarkCamelCaseToSnakeCase/PascalCase BenchmarkCamelCaseToSnakeCase/PascalCase-12 7169013 139.8 ns/op 136 B/op 5 allocs/op BenchmarkCamelCaseToSnakeCase/ThisIsALongerStringWithMultipleWords BenchmarkCamelCaseToSnakeCase/ThisIsALongerStringWithMultipleWords-12 2767956 402.4 ns/op 552 B/op 7 allocs/op BenchmarkCamelCaseToSnakeCase/HTTPRequestHandler BenchmarkCamelCaseToSnakeCase/HTTPRequestHandler-12 4547570 232.3 ns/op 280 B/op 6 allocs/op BenchmarkCamelCaseToSnakeCase/OAuth2ClientID BenchmarkCamelCaseToSnakeCase/OAuth2ClientID-12 5208450 202.9 ns/op 272 B/op 6 allocs/op ``` ## After ### BenchmarkGenerateRandomAlphanumericString ``` BenchmarkGenerateRandomAlphanumericString/8 BenchmarkGenerateRandomAlphanumericString/8-12 10384836 114.7 ns/op 24 B/op 2 allocs/op BenchmarkGenerateRandomAlphanumericString/16 BenchmarkGenerateRandomAlphanumericString/16-12 3644259 303.2 ns/op 40 B/op 2 allocs/op BenchmarkGenerateRandomAlphanumericString/32 BenchmarkGenerateRandomAlphanumericString/32-12 3281170 336.1 ns/op 80 B/op 2 allocs/op BenchmarkGenerateRandomAlphanumericString/64 BenchmarkGenerateRandomAlphanumericString/64-12 2738896 410.4 ns/op 160 B/op 2 allocs/op BenchmarkGenerateRandomAlphanumericString/128 BenchmarkGenerateRandomAlphanumericString/128-12 1993492 572.8 ns/op 304 B/op 2 allocs/op ``` ### BenchmarkCapitalizeFirstLetter ``` BenchmarkCapitalizeFirstLetter/8 BenchmarkCapitalizeFirstLetter/8-12 31061524 39.14 ns/op 8 B/op 1 allocs/op BenchmarkCapitalizeFirstLetter/16 BenchmarkCapitalizeFirstLetter/16-12 18976692 62.44 ns/op 16 B/op 1 allocs/op BenchmarkCapitalizeFirstLetter/32 BenchmarkCapitalizeFirstLetter/32-12 11386884 105.3 ns/op 32 B/op 1 allocs/op BenchmarkCapitalizeFirstLetter/64 BenchmarkCapitalizeFirstLetter/64-12 5534036 191.9 ns/op 64 B/op 1 allocs/op BenchmarkCapitalizeFirstLetter/128 BenchmarkCapitalizeFirstLetter/128-12 3081794 364.9 ns/op 128 B/op 1 allocs/op ``` ### BenchmarkCamelCaseToSnakeCase ``` BenchmarkCamelCaseToSnakeCase/simpleCase BenchmarkCamelCaseToSnakeCase/simpleCase-12 24040098 48.83 ns/op 16 B/op 1 allocs/op BenchmarkCamelCaseToSnakeCase/PascalCase BenchmarkCamelCaseToSnakeCase/PascalCase-12 23784078 49.48 ns/op 16 B/op 1 allocs/op BenchmarkCamelCaseToSnakeCase/ThisIsALongerStringWithMultipleWords BenchmarkCamelCaseToSnakeCase/ThisIsALongerStringWithMultipleWords-12 6214612 164.2 ns/op 48 B/op 1 allocs/op BenchmarkCamelCaseToSnakeCase/HTTPRequestHandler BenchmarkCamelCaseToSnakeCase/HTTPRequestHandler-12 14924120 80.26 ns/op 24 B/op 1 allocs/op BenchmarkCamelCaseToSnakeCase/OAuth2ClientID BenchmarkCamelCaseToSnakeCase/OAuth2ClientID-12 15093292 79.50 ns/op 48 B/op 2 allocs/op ``` --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
OVERLORD added the pull-request label 2025-10-09 16:58:47 +03:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/pocket-id-pocket-id-2#869