string to character code hex string
Moritz Maxeiner via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sat Sep 2 10:45:30 PDT 2017
On Saturday, 2 September 2017 at 16:23:57 UTC, bitwise wrote:
> On Saturday, 2 September 2017 at 15:53:25 UTC, bitwise wrote:
>> [...]
>
> This seems to work well enough.
>
> string toAsciiHex(string str)
> {
> import std.array : appender;
>
> auto ret = appender!string(null);
> ret.reserve(str.length * 2);
> foreach(c; str) ret.put(format!"%x"(c));
> return ret.data;
> }
Note: Each of those format calls is going to allocate a new
string, followed by put copying that new string's content over
into the appender, leaving you with \theta(str.length) tiny
memory chunks that aren't used anymore for the GC to eventually
collect.
If this (unnecessary waste) is of concern to you (and from the
fact that you used ret.reserve I assume it is), then the easy fix
is to use `sformat` instead of `format`:
---
string toHex(string str)
{
import std.format : sformat;
import std.exception: assumeUnique;
auto ret = new char[str.length * 2];
size_t len;
foreach (c; str)
{
auto slice = sformat!"%x"(ret[len..$], c);
//auto slice = toHex(ret[len..$], c);
assert (slice.length <= 2);
len += slice.length;
}
return ret[0..len].assumeUnique;
}
---
If you want to cut out the format import entirely, notice the
`auto slice = toHex...` line, which can be implemented like this
(always returns two chars):
---
char[] toHex(char[] buf, char c)
{
import std.ascii : lowerHexDigits;
assert (buf.length >= 2);
buf[0] = lowerHexDigits[(c & 0xF0) >> 4];
buf[1] = lowerHexDigits[c & 0x0F];
return buf[0..2];
}
---
More information about the Digitalmars-d-learn
mailing list