-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
ComptimeStringMap: return a regular struct and optimize #19719
ComptimeStringMap: return a regular struct and optimize #19719
Conversation
Could the name be changed while we're breaking the API? Instead of |
sure no problem. will work on that now. |
should I leave in |
865a9a6
to
1953227
Compare
3237536
to
7ae12a5
Compare
This is done. We'll see how many typos i made 😄 |
CI doesn't like that I've renamed
|
7ae12a5
to
7ad58ca
Compare
For now, I've moved back to the original name so we can make progress. |
I think you need to also change this line (in samencommit), so that CMake knows this "dependency" is renamed: Line 225 in 3c5e840
|
7ad58ca
to
1d4d4dc
Compare
Thanks! Just pushed this change. |
cebaa3f
to
b7f3025
Compare
That's what I was going for. |
Sounds good! Thats an easy change. Also, any thoughts about whether I should remove |
|
Not bad. I think I'd prefer |
b7f3025
to
1e7fad0
Compare
@Vexu done - renamed |
1e7fad0
to
21a3a57
Compare
Perf point: building my simdjzon project with around 7000 loc zig files in src folder. Note that I'm not super confident in my process so here are some notes:
.../zig/simdjzon $ zig version
0.13.0-dev.8+c352845e8
.../zig/simdjzon $ ../zig/stage4/bin/zig version
0.13.0-dev.9+21a3a5710
.../zig/simdjzon $ poop 'zig build-exe -fno-emit-bin -ODebug --dep simdjzon -Mroot=src/main.zig --dep build_options -Msimdjzon=src/simdjzon.zig -Mbuild_options=zig-cache/c/8caf24ab22f7fa50f13c4c948a6b8cca/options.zig --cache-dir zig-cache --global-cache-dir /home/travis/.cache/zig --name simdjzon' '../zig/stage4/bin/zig build-exe -fno-emit-bin -ODebug --dep simdjzon -Mroot=src/main.zig --dep build_options -Msimdjzon=src/simdjzon.zig -Mbuild_options=zig-cache/c/8caf24ab22f7fa50f13c4c948a6b8cca/options.zig --cache-dir zig-cache --global-cache-dir /home/travis/.cache/zig --name simdjzon'
Benchmark 1 (36 runs): zig build-exe -fno-emit-bin -ODebug --dep simdjzon -Mroot=src/main.zig --dep build_options -Msimdjzon=src/simdjzon.zig -Mbuild_options=zig-cache/c/8caf24ab22f7fa50f13c4c948a6b8cca/options.zig --cache-dir zig-cache --global-cache-dir /home/travis/.cache/zig --name simdjzon
measurement mean ± σ min … max outliers delta
wall_time 139ms ± 1.58ms 136ms … 144ms 1 ( 3%) 0%
peak_rss 111MB ± 285KB 111MB … 112MB 1 ( 3%) 0%
cpu_cycles 619M ± 3.32M 612M … 626M 4 (11%) 0%
instructions 986M ± 4.88K 986M … 986M 2 ( 6%) 0%
cache_references 58.8M ± 356K 58.1M … 59.5M 0 ( 0%) 0%
cache_misses 8.02M ± 106K 7.85M … 8.24M 0 ( 0%) 0%
branch_misses 4.60M ± 28.0K 4.54M … 4.68M 1 ( 3%) 0%
Benchmark 2 (41 runs): ../zig/stage4/bin/zig build-exe -fno-emit-bin -ODebug --dep simdjzon -Mroot=src/main.zig --dep build_options -Msimdjzon=src/simdjzon.zig -Mbuild_options=zig-cache/c/8caf24ab22f7fa50f13c4c948a6b8cca/options.zig --cache-dir zig-cache --global-cache-dir /home/travis/.cache/zig --name simdjzon
measurement mean ± σ min … max outliers delta
wall_time 123ms ± 1.24ms 121ms … 128ms 1 ( 2%) ⚡- 11.5% ± 0.5%
peak_rss 106MB ± 178KB 106MB … 106MB 2 ( 5%) ⚡- 4.5% ± 0.1%
cpu_cycles 465M ± 3.15M 461M … 479M 2 ( 5%) ⚡- 24.8% ± 0.2%
instructions 718M ± 4.03K 718M … 718M 0 ( 0%) ⚡- 27.1% ± 0.0%
cache_references 52.7M ± 342K 52.1M … 53.5M 0 ( 0%) ⚡- 10.4% ± 0.3%
cache_misses 7.56M ± 133K 7.30M … 7.96M 2 ( 5%) ⚡- 5.8% ± 0.7%
branch_misses 3.13M ± 19.2K 3.08M … 3.18M 3 ( 7%) ⚡- 31.9% ± 0.2% This seems too good to be true. Can anyone spot any mistakes or maybe try reproducing with this branch and building a different project? |
I got some feedback on discord from @jacobly0 @nektro and
The consensus I think is that this benchmark isn't reliable since there are too many moving parts such as caching. So I believe my previous benchmarks are a better measurement. |
this patch renames ComptimeStringMap to StaticStringMap, makes it accept only a single type parameter, and return a known struct type instead of an anonymous struct. initial motivation for these changes was to reduce the 'very long type names' issue described here ziglang#19682. this breaks the previous API. users will now need to write: `const map = std.StaticStringMap(T).initComptime(kvs_list);` * move `kvs_list` param from type param to an `initComptime()` param * new public methods * `keys()`, `values()` helpers * `init(allocator)`, `deinit(allocator)` for runtime data * `getLongestPrefix(str)`, `getLongestPrefixIndex(str)` - i'm not sure these belong but have left in for now incase they are deemed useful * performance notes: * i posted some benchmarking results here: https://github.com/travisstaloch/comptime-string-map-revised/issues/1 * i noticed a speedup reducing the size of the struct from 48 to 32 bytes and thus use u32s instead of usize for all length fields * i noticed speedup storing KVs as a struct of arrays * latest benchmark shows these wall_time improvements for debug/safe/small/fast builds: -6.6% / -10.2% / -19.1% / -8.9%. full output in link above.
21a3a57
to
ea50d26
Compare
pub inline fn initComptime(comptime kvs_list: anytype) Self { | ||
comptime { | ||
@setEvalBranchQuota(30 * kvs_list.len); |
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.
@Vexu done. This seems to be just big enough. I've added another test at bottom with a kvs_list of length 1000.
/// Returns the longest key, value pair where key is a prefix of `str` | ||
/// else null. |
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.
Nit: This makes it sound as if the value contributes to the length calculation.
/// Returns the longest key, value pair where key is a prefix of `str` | |
/// else null. | |
/// Returns the key-value pair where key is the longest prefix of `str` | |
/// else null. |
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.
Thanks. 👍 . I'll make sure to change this next review if getLongestPrefix()
is approved.
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.
Ah merged already. Will have to be a follow up.
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.
I've added these changes in #19823 along with a note about time complexity
Can you edit your PR description to be correct so that I can use it for release notes in the future? nice work, btw. |
Thanks! Done. And will do. |
Not only did the name change, but the initialization procedure and types also needed to be tweaked. This made me realize that with my other memory management changes, the attempts to lookup shorthands for chromatic and whole-tone patterns was failing. That was due to the Pitch.asText() return value going out of scope, so it was always blank. Instead of trying to use a static array and be tricky, we'll pass in an allocator like I probably should have to begin with. See: - ziglang/zig#19719
this patch renames ComptimeStringMap to StaticStringMap, makes it
accept only a single type parameter, and return a known struct type
instead of an anonymous struct. initial motivation for these changes
was to reduce the 'very long type names' issue described here
#19682.
this breaks the previous API. users will now need to write:
const map = std.StaticStringMap(T).initComptime(kvs_list);
kvs_list
param from type param to aninitComptime()
paramkeys()
,values()
helpersinit(allocator)
,deinit(allocator)
for runtime datagetLongestPrefix(str)
,getLongestPrefixIndex(str)
- i'm not surethese belong but have left in for now incase they are deemed useful
travisstaloch/comptime-string-map-revised#1
bytes and thus use u32s instead of usize for all length fields
debug/safe/small/fast builds: -6.6% / -10.2% / -19.1% / -8.9%. full
output in link above.