I was profiling my program with callgrind and saw that a lot of time was spent in countUntil (std.algorithm.searching) on strings. I had chosen to use it instead of indexOf (std.string), with the plain assumption that countUntil wouldn't decode, while indexOf would.

Comparing microbenchmarks between the two I see that countUntil is some 7x slower.


import std.stdio : writeln;
import std.string : indexOf;
import std.algorithm.searching : countUntil;
import std.datetime;

enum line = ":zorael!~n...@asdf.asdf.asdf PRIVMSG #d :Hello world!";
enum iterations = 1_000_000;

void main()
{
    StopWatch sw;

    sw.start();
    foreach (i; 0..iterations)
    {
        line.indexOf(" :");
    }
    sw.stop();

    immutable usecsIndexOf = sw.peek().usecs;
        
    sw.reset();
    sw.start();
    foreach (i; 0..iterations)
    {
        line.countUntil(" :");
    }
    sw.stop();

    immutable usecsCountUntil = sw.peek().usecs;

    writeln("indexOf:    ", usecsIndexOf.usecs);
    writeln("countUntil: ", usecsCountUntil.usecs);
    writeln(cast(double)usecsCountUntil/usecsIndexOf, "x");
}


https://dpaste.dzfl.pl/0319edb79ec8 gives the output:

    indexOf:    160 ms and 534 μs
    countUntil: 1 sec, 146 ms, and 842 μs
    7.14392x

What is the fundamental difference between the two? When should I ever use countUntil on strings?

Reply via email to