How to loop through characters of a string in D language?
Salih Dincer
salihdb at hotmail.com
Thu Dec 23 07:14:35 UTC 2021
On Monday, 13 December 2021 at 09:36:57 UTC, Ola Fosheim Grøstad
wrote:
> ```d
> @safe:
>
> string prematureoptimizations(string s, char stripchar)
> @trusted {
> import core.memory;
> immutable uint flags =
> GC.BlkAttr.NO_SCAN|GC.BlkAttr.APPENDABLE;
> char* begin = cast(char*)GC.malloc(s.length+1, flags);
> char* end = begin + 1;
> foreach(c; s) {
> immutable size_t notsemicolon = c != stripchar;
> // hack: avoid conditional by writing semicolon outside
> buffer
> *(end - notsemicolon) = c;
> end += notsemicolon;
> }
> immutable size_t len = end - begin - 1;
> begin = cast(char*)GC.realloc(begin, len, flags);
> return cast(string)begin[0..len];
> }
>
> void main() {
> import std.stdio;
> string str = "abc;def;ab";
> writeln(prematureoptimizations(str, ';'));
> }
> ```
It seems faster than algorithms in Phobos. We would love to see
this in our new Phobos.
```d
enum str = "abc;def;gh";
enum res = "abcdefgh";
void main()
{
void mallocReplace()
{
import core.memory;
immutable uint flags =
GC.BlkAttr.NO_SCAN|
GC.BlkAttr.APPENDABLE;
char* begin = cast(char*)GC.malloc(str.length+1, flags);
char* end = begin + 1;
foreach(c; str)
{
immutable size_t f = c != ';';
*(end - f) = c;
end += f;
}
immutable size_t len = end - begin - 1;
begin = cast(char*)GC.realloc(begin, len, flags);
assert(begin[0..len] == res);
}
void normalReplace()
{
import std.string;
string result = str.replace(';',"");
assert(result == res);
}
void delegate() t1 = &normalReplace;
void delegate() t2 = &mallocReplace;
import std.stdio : writefln;
import std.datetime.stopwatch : benchmark;
auto bm = benchmark!(t1, t2)(1_000_000);
writefln("Replace: %s msecs", bm[0].total!"msecs");
writefln("Malloc : %s msecs", bm[1].total!"msecs");
}/* Console Out:
Replace: 436 msecs
Malloc : 259 msecs
*/
```
More information about the Digitalmars-d-learn
mailing list