www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - str.to!Enum performance

reply realhet <real_het hotmail.com> writes:
Hi,

I've compared 2 ways of converting enum identifier strings to 
enum value:
- implemented with a manual associative array: 45ms
- implemented by std.conv.to: `name.to!Enum()`: 1299ms

(batch= 500_000, I tested with looking up the Segoe MDL2 Asset 
symbol characters)

Anyone can tell me how std.to() is doing the conversion, is it 
using the simplest way: linear search?
Can anyone point it out in the sources?

I have no luck finding it in std.conv, it's quite big. I've only 
found the opposite way.

Thanks in advance.
Sep 07
next sibling parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
https://github.com/dlang/phobos/blob/master/std/conv.d#L1103

Appears to be it.
Sep 07
next sibling parent reply realhet <real_het hotmail.com> writes:
On Monday, 7 September 2026 at 15:24:52 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 https://github.com/dlang/phobos/blob/master/std/conv.d#L1103

 Appears to be it.
Thank You! So it is a switch() of string cases. And that particular implementation is not allowed to do fancy, resource-involving stuff like an associative array. I will remember this. And also I will remember that with integer cases, the switch can do crazy fast jump tables.
Sep 07
next sibling parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 08/09/2026 4:01 AM, realhet wrote:
 On Monday, 7 September 2026 at 15:24:52 UTC, Richard (Rikki) Andrew 
 Cattermole wrote:
 https://github.com/dlang/phobos/blob/master/std/conv.d#L1103

 Appears to be it.
Thank You! So it is a switch() of string cases. And that particular implementation is not allowed to do fancy, resource-involving stuff like an associative array. I will remember this. And also I will remember that with integer cases, the switch can do crazy fast jump tables.
It probably needs optimizing. Have at it.
Sep 07
next sibling parent realhet <real_het hotmail.com> writes:
On Monday, 7 September 2026 at 16:20:42 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 On 08/09/2026 4:01 AM, realhet wrote:
 On Monday, 7 September 2026 at 15:24:52 UTC, Richard (Rikki) 
 Andrew Cattermole wrote:
It probably needs optimizing. Have at it.
Yepp, and I just found my tools for it. I almost forgot about those. ```d enum EnumMemberNames(T) = is(T==enum) ? [__traits(allMembers, T)] : []; enum EnumAssocArray(alias T) = /+keys = enumMember.text, values = enumMember+/ ((){ T[string] o; foreach(i, name; EnumMemberNames!T) o[name] = [EnumMembers!T][i]; return o; })(); ``` ``` I only create the AA if it is needed in runtime. This way the .exe file only contains the enum member names as separate zero terminated string literals. All strings are aligned to 16 bytes. Anyways, the most important is to know what's going under the hood. Thx!
Sep 07
prev sibling parent reply "H. S. Teoh" <hsteoh qfbox.info> writes:
On Tue, Sep 08, 2026 at 04:20:42AM +1200, Richard (Rikki) Andrew Cattermole via
Digitalmars-d-learn wrote:
 On 08/09/2026 4:01 AM, realhet wrote:
 On Monday, 7 September 2026 at 15:24:52 UTC, Richard (Rikki) Andrew
 Cattermole wrote:
 https://github.com/dlang/phobos/blob/master/std/conv.d#L1103
 
 Appears to be it.
Thank You! So it is a switch() of string cases. And that particular implementation is not allowed to do fancy, resource-involving stuff like an associative array. I will remember this. And also I will remember that with integer cases, the switch can do crazy fast jump tables.
It probably needs optimizing. Have at it.
Weren't string switches one of the original reasons for moving the implementation of switch into a druntime template? The argument was that it would allow more flexibility in implementing fast string lookups. Apparently it hasn't happened yet. :-/ T -- In a world without fences, who needs Windows and Gates? -- Christian Surchi
Sep 07
parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 08/09/2026 4:35 AM, H. S. Teoh wrote:
 On Tue, Sep 08, 2026 at 04:20:42AM +1200, Richard (Rikki) Andrew Cattermole
via Digitalmars-d-learn wrote:
 On 08/09/2026 4:01 AM, realhet wrote:
 On Monday, 7 September 2026 at 15:24:52 UTC, Richard (Rikki) Andrew
 Cattermole wrote:
 https://github.com/dlang/phobos/blob/master/std/conv.d#L1103

 Appears to be it.
Thank You! So it is a switch() of string cases. And that particular implementation is not allowed to do fancy, resource-involving stuff like an associative array. I will remember this. And also I will remember that with integer cases, the switch can do crazy fast jump tables.
It probably needs optimizing. Have at it.
Weren't string switches one of the original reasons for moving the implementation of switch into a druntime template? The argument was that it would allow more flexibility in implementing fast string lookups. Apparently it hasn't happened yet. :-/ T
I have no knowledge of templating switch statements. But I am aware of jump table optimizations, which are done by backends if they recognize the condition + jump tree.
Sep 07
prev sibling parent Nick Treleaven <nick geany.org> writes:
On Monday, 7 September 2026 at 16:01:25 UTC, realhet wrote:
 On Monday, 7 September 2026 at 15:24:52 UTC, Richard (Rikki) 
 Andrew Cattermole wrote:
 https://github.com/dlang/phobos/blob/master/std/conv.d#L1103

 Appears to be it.
Thank You! So it is a switch() of string cases.
Only when `EnumMembers!S.length <= 50`. Maybe you could benchmark <= 50 members vs your AA?
 And that particular implementation is not allowed to do fancy, 
 resource-involving stuff like an associative array. I will 
 remember this. And also I will remember that with integer 
 cases, the switch can do crazy fast jump tables.
Sep 09
prev sibling parent Johan <j j.nl> writes:
On Monday, 7 September 2026 at 15:24:52 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 https://github.com/dlang/phobos/blob/master/std/conv.d#L1103

 Appears to be it.
That link is to converting enum --> string. The OP is converting string --> enum. Which is here: https://github.com/dlang/phobos/blob/4194510d7d5ca88267cd009402f001429fabc645/std/conv.d#L3057
Sep 10
prev sibling parent reply Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
On Monday, 7 September 2026 at 15:22:12 UTC, realhet wrote:
 Hi,

 I've compared 2 ways of converting enum identifier strings to 
 enum value:
 - implemented with a manual associative array: 45ms
 - implemented by std.conv.to: `name.to!Enum()`: 1299ms
One hotspot is the call to `NoDuplicates` at https://github.com/dlang/phobos/blob/master/std/conv.d#L1109 If you know that your enum doesn't contain any duplicates you can use my ```d /++ Faster replacement of `std.conv.to!(string)` for enum `T` with unique members. +/ string toStringUnique(T)(in T arg) nothrow nogc if (is(T == enum)) { final switch (arg) { foreach (member; __traits(allMembers, T)) { // instead of way slower `EnumMembers` case __traits(getMember, T, member): return member; } } } pure nothrow safe nogc unittest { static enum E : ubyte { a = 0, b = 1 } assert(E.a.toStringUnique() == "a"); assert(E.a.toStringUnique() == "a"); } ``` .
Sep 09
parent Paul Backus <snarwin gmail.com> writes:
On Wednesday, 9 September 2026 at 10:54:14 UTC, Per Nordlöw wrote:
 On Monday, 7 September 2026 at 15:22:12 UTC, realhet wrote:
 Hi,

 I've compared 2 ways of converting enum identifier strings to 
 enum value:
 - implemented with a manual associative array: 45ms
 - implemented by std.conv.to: `name.to!Enum()`: 1299ms
One hotspot is the call to `NoDuplicates` at https://github.com/dlang/phobos/blob/master/std/conv.d#L1109
Given that this thread is talking about runtime performance, not compile time, I don't see how this could possibly be relevant.
Sep 09