Skip to content

Commit 86bf50c

Browse files
committed
Optimize StaticStringMap, add StaticArrayMap. Remove runtime .init()
StaticArrayMap and StaticArrayMapWithEql are more alternatives to StaticStringMap and StaticStringMapWithEql, the difference being that they can have an array of any type of uniquely represented data as the key, rather than just an array of u8. StaticStringMapIgnoreCase has been added to provide a case-insensitive definition of StaticArrayMap. While you *can* use StaticArrayMapWithEql, StaticStringMapIgnoreCase is a common usecase of StaticStringMap while also being optimized with SIMD. The construction of StaticStringMap (provided by StaticArrayMap) has changed to be comptime-only. This change allows us to greatly improve the generated machine code through sorting the keys by length and comparing multiple bytes at the same time. The breaking changes include: - StaticStringMapWithEql interface has changed - specifically, take a look at the function interface of the eql function, which now takes a comptime-time known length, a comptime-time known array of an expected key, a runtime-known array of the recieved key, and returns a boolean indicating whether the two classify as matching. - The getLongestPrefix and getLongestPrefixIndex functions have been removed. They did not see much use. As a result of these changes, performance is greatly improved. If you have been using a runtime initialization of a StaticStringMap, consider using comptime initialization or std.StaticStringMap. Many test cases depended on getLongestPrefix, getLongestPrefixIndex, or runtime initialization. Those test cases have been removed, as they are no longer testing existing code.
1 parent 42dac40 commit 86bf50c

File tree

8 files changed

+518
-638
lines changed

8 files changed

+518
-638
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ set(ZIG_STAGE2_SOURCES
479479
lib/std/process/Child.zig
480480
lib/std/sort.zig
481481
lib/std/start.zig
482-
lib/std/static_string_map.zig
482+
lib/std/static_array_map.zig
483483
lib/std/std.zig
484484
lib/std/time.zig
485485
lib/std/treap.zig

lib/compiler/resinator/lang.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ test tagToId {
119119
}
120120

121121
test "exhaustive tagToId" {
122-
inline for (@typeInfo(LanguageId).Enum.fields) |field| {
122+
inline for (@typeInfo(LanguageId).@"enum".fields) |field| {
123123
const id = tagToId(field.name) catch |err| {
124124
std.debug.print("tag: {s}\n", .{field.name});
125125
return err;

lib/compiler/resinator/rc.zig

Lines changed: 13 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,7 @@ pub const Resource = enum {
4747
fontdir_num,
4848
manifest_num,
4949

50-
const map = std.StaticStringMapWithEql(
51-
Resource,
52-
std.static_string_map.eqlAsciiIgnoreCase,
53-
).initComptime(.{
50+
const map = std.StaticStringMapIgnoreCase(Resource).initComptime(.{
5451
.{ "ACCELERATORS", .accelerators },
5552
.{ "BITMAP", .bitmap },
5653
.{ "CURSOR", .cursor },
@@ -160,19 +157,13 @@ pub const OptionalStatements = enum {
160157
menu,
161158
style,
162159

163-
pub const map = std.StaticStringMapWithEql(
164-
OptionalStatements,
165-
std.static_string_map.eqlAsciiIgnoreCase,
166-
).initComptime(.{
160+
pub const map = std.StaticStringMapIgnoreCase(OptionalStatements).initComptime(.{
167161
.{ "CHARACTERISTICS", .characteristics },
168162
.{ "LANGUAGE", .language },
169163
.{ "VERSION", .version },
170164
});
171165

172-
pub const dialog_map = std.StaticStringMapWithEql(
173-
OptionalStatements,
174-
std.static_string_map.eqlAsciiIgnoreCase,
175-
).initComptime(.{
166+
pub const dialog_map = std.StaticStringMapIgnoreCase(OptionalStatements).initComptime(.{
176167
.{ "CAPTION", .caption },
177168
.{ "CLASS", .class },
178169
.{ "EXSTYLE", .exstyle },
@@ -206,10 +197,7 @@ pub const Control = enum {
206197
state3,
207198
userbutton,
208199

209-
pub const map = std.StaticStringMapWithEql(
210-
Control,
211-
std.static_string_map.eqlAsciiIgnoreCase,
212-
).initComptime(.{
200+
pub const map = std.StaticStringMapIgnoreCase(Control).initComptime(.{
213201
.{ "AUTO3STATE", .auto3state },
214202
.{ "AUTOCHECKBOX", .autocheckbox },
215203
.{ "AUTORADIOBUTTON", .autoradiobutton },
@@ -243,10 +231,7 @@ pub const Control = enum {
243231
};
244232

245233
pub const ControlClass = struct {
246-
pub const map = std.StaticStringMapWithEql(
247-
res.ControlClass,
248-
std.static_string_map.eqlAsciiIgnoreCase,
249-
).initComptime(.{
234+
pub const map = std.StaticStringMapIgnoreCase(res.ControlClass).initComptime(.{
250235
.{ "BUTTON", .button },
251236
.{ "EDIT", .edit },
252237
.{ "STATIC", .static },
@@ -295,10 +280,7 @@ pub const MenuItem = enum {
295280
menuitem,
296281
popup,
297282

298-
pub const map = std.StaticStringMapWithEql(
299-
MenuItem,
300-
std.static_string_map.eqlAsciiIgnoreCase,
301-
).initComptime(.{
283+
pub const map = std.StaticStringMapIgnoreCase(MenuItem).initComptime(.{
302284
.{ "MENUITEM", .menuitem },
303285
.{ "POPUP", .popup },
304286
});
@@ -315,10 +297,7 @@ pub const MenuItem = enum {
315297
menubarbreak,
316298
menubreak,
317299

318-
pub const map = std.StaticStringMapWithEql(
319-
Option,
320-
std.static_string_map.eqlAsciiIgnoreCase,
321-
).initComptime(.{
300+
pub const map = std.StaticStringMapIgnoreCase(Option).initComptime(.{
322301
.{ "CHECKED", .checked },
323302
.{ "GRAYED", .grayed },
324303
.{ "HELP", .help },
@@ -333,10 +312,7 @@ pub const ToolbarButton = enum {
333312
button,
334313
separator,
335314

336-
pub const map = std.StaticStringMapWithEql(
337-
ToolbarButton,
338-
std.static_string_map.eqlAsciiIgnoreCase,
339-
).initComptime(.{
315+
pub const map = std.StaticStringMapIgnoreCase(ToolbarButton).initComptime(.{
340316
.{ "BUTTON", .button },
341317
.{ "SEPARATOR", .separator },
342318
});
@@ -351,10 +327,7 @@ pub const VersionInfo = enum {
351327
file_type,
352328
file_subtype,
353329

354-
pub const map = std.StaticStringMapWithEql(
355-
VersionInfo,
356-
std.static_string_map.eqlAsciiIgnoreCase,
357-
).initComptime(.{
330+
pub const map = std.StaticStringMapIgnoreCase(VersionInfo).initComptime(.{
358331
.{ "FILEVERSION", .file_version },
359332
.{ "PRODUCTVERSION", .product_version },
360333
.{ "FILEFLAGSMASK", .file_flags_mask },
@@ -369,10 +342,7 @@ pub const VersionBlock = enum {
369342
block,
370343
value,
371344

372-
pub const map = std.StaticStringMapWithEql(
373-
VersionBlock,
374-
std.static_string_map.eqlAsciiIgnoreCase,
375-
).initComptime(.{
345+
pub const map = std.StaticStringMapIgnoreCase(VersionBlock).initComptime(.{
376346
.{ "BLOCK", .block },
377347
.{ "VALUE", .value },
378348
});
@@ -386,10 +356,7 @@ pub const TopLevelKeywords = enum {
386356
characteristics,
387357
stringtable,
388358

389-
pub const map = std.StaticStringMapWithEql(
390-
TopLevelKeywords,
391-
std.static_string_map.eqlAsciiIgnoreCase,
392-
).initComptime(.{
359+
pub const map = std.StaticStringMapIgnoreCase(TopLevelKeywords).initComptime(.{
393360
.{ "LANGUAGE", .language },
394361
.{ "VERSION", .version },
395362
.{ "CHARACTERISTICS", .characteristics },
@@ -408,10 +375,7 @@ pub const CommonResourceAttributes = enum {
408375
shared,
409376
nonshared,
410377

411-
pub const map = std.StaticStringMapWithEql(
412-
CommonResourceAttributes,
413-
std.static_string_map.eqlAsciiIgnoreCase,
414-
).initComptime(.{
378+
pub const map = std.StaticStringMapIgnoreCase(CommonResourceAttributes).initComptime(.{
415379
.{ "PRELOAD", .preload },
416380
.{ "LOADONCALL", .loadoncall },
417381
.{ "FIXED", .fixed },
@@ -432,10 +396,7 @@ pub const AcceleratorTypeAndOptions = enum {
432396
shift,
433397
control,
434398

435-
pub const map = std.StaticStringMapWithEql(
436-
AcceleratorTypeAndOptions,
437-
std.static_string_map.eqlAsciiIgnoreCase,
438-
).initComptime(.{
399+
pub const map = std.StaticStringMapIgnoreCase(AcceleratorTypeAndOptions).initComptime(.{
439400
.{ "VIRTKEY", .virtkey },
440401
.{ "ASCII", .ascii },
441402
.{ "NOINVERT", .noinvert },

lib/std/meta.zig

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,14 @@ pub fn stringToEnum(comptime T: type, str: []const u8) ?T {
2222
// - https://github.com/ziglang/zig/issues/4055
2323
// - https://github.com/ziglang/zig/issues/3863
2424
if (@typeInfo(T).@"enum".fields.len <= 100) {
25-
const kvs = comptime build_kvs: {
25+
const map = comptime build_kvs: {
2626
const EnumKV = struct { []const u8, T };
2727
var kvs_array: [@typeInfo(T).@"enum".fields.len]EnumKV = undefined;
2828
for (@typeInfo(T).@"enum".fields, 0..) |enumField, i| {
2929
kvs_array[i] = .{ enumField.name, @field(T, enumField.name) };
3030
}
31-
break :build_kvs kvs_array[0..];
31+
break :build_kvs std.StaticStringMap(T).initComptime(kvs_array);
3232
};
33-
const map = std.StaticStringMap(T).initComptime(kvs);
3433
return map.get(str);
3534
} else {
3635
inline for (@typeInfo(T).@"enum".fields) |enumField| {

0 commit comments

Comments
 (0)