Bug 17210 – DMD's Failure to Inline Calls in std.array.Appender.put Cause 3x Slowdown

Status
NEW
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2017-02-20T18:29:56Z
Last change time
2024-12-13T18:51:40Z
Keywords
performance
Assigned to
No Owner
Creator
Jack Stouffer
Moved to GitHub: dmd#17790 →

Attachments

IDFilenameSummaryContent-TypeSize
1637appender_ranges.dAppender Benchmarktext/plain1084

Comments

Comment #0 by jack — 2017-02-20T18:29:56Z
Consider this code in Appender void put(U)(U item) if (canPutItem!U) { static if (isSomeChar!T && isSomeChar!U && T.sizeof < U.sizeof) { /* may throwable operation: * - std.utf.encode */ // must do some transcoding around here import std.utf : encode; Unqual!T[T.sizeof == 1 ? 4 : 2] encoded; auto len = encode(encoded, item); put(encoded[0 .. len]); } else { ensureAddable(1); immutable len = _data.arr.length; import std.conv : emplaceRef; auto bigData = (() @trusted => _data.arr.ptr[0 .. len + 1])(); emplaceRef!(Unqual!T)(bigData[len], cast(Unqual!T)item); //We do this at the end, in case of exceptions _data.arr = bigData; } } Manually inline-ing the call to emplaceRef for basic types leads to 3x faster code. Replace the non-char type code path with this code, static if (isBasicType!U) { auto d = _data.arr.ptr[0 .. len + 1]; d[len] = cast(Unqual!T) item; _data.arr = d; } else { import std.conv : emplaceRef; auto bigData = (() @trusted => _data.arr.ptr[0 .. len + 1])(); emplaceRef!(Unqual!T)(bigData[len], cast(Unqual!T)item); //We do this at the end, in case of exceptions _data.arr = bigData; } Functionally, these different code paths are exactly the same. Here's the numbers before and after Before: 3 secs, 29 ms, and 842 μs After: 1 sec, 109 ms, 734 μs, and 6 hnsecs
Comment #1 by jack — 2017-02-20T18:32:39Z
Created attachment 1637 Appender Benchmark
Comment #2 by jack — 2017-03-03T22:43:39Z
BTW, making this @safe by changing the manual code to static if (isBasicType!U) { auto d = (() @trusted => _data.arr.ptr[0 .. len + 1])(); d[len] = cast(Unqual!T) item; _data.arr = d; } makes the code twice as slow as the other manual version
Comment #3 by robert.schadek — 2024-12-13T18:51:40Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17790 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB