Skip to content

Conversation

@jmdavis
Copy link
Member

@jmdavis jmdavis commented May 6, 2017

std.datetime.package has StopWatch, benchmark, comparingBenchmark, and
measureTime, all of which use TickDuration (which would be deprecated,
but it can't be deprecated as long as those functions in std.datetime
are deprecated). This commit introduces
std.datetime.stopwatch to replace those functions in std.datetime. In
order to avoid symbol conflicts, std.datetime.stopwatch will not be
publicly import in std.datetime.package until the old symbols have been
removed.

std.datetime.experimental.stopwatch contains StopWatch and benchmark
which have essentially the same APIs as the ones in
std.datetime.package, but they use MonoTime and Duration.

comparingBenchmark has not been ported to MonoTime and Duration, because
it is simply a wrapper around benchmark.

measureTime has not been ported to MonoTime and Duration, because it is
equivalent to using StopWatch with a scope(exit) statement.

The old functionality will be deprecated the major release after the new
symbols have been introduced.

@jmdavis
Copy link
Member Author

jmdavis commented May 6, 2017

FYI: I've already talked about these changes with Andrei, and he's okay with them.

Copy link
Contributor

@wilzbach wilzbach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned offline I think this is an excellent opportunity to change benchmark, s.t. it will avoid optimization the benchmarked functions away. Though, this could be easily done as a follow-up as well.

Moreover, I added a couple of nits & questions.

If $(D StopWatch.init) is used, then the constructed StopWatch isn't
running (and can't be, since no constructor ran).
+/
this(AutoStart autostart) @safe nothrow @nogc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this has been discussed when StopWatch has been introduced, but just out of interest is setting a default being avoid to force the user to be explicit?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside from whether that would help or harm usability, it wouldn't work in D, because then it would be a default constructor.

{
sw.reset();
foreach (_; 0 .. n)
fun[i]();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One minor thing that one nearly always has to think about is that a reasonably smart optimizer will just remove this code block.
There are a couple of tricks to avoid this behavior, at least:

Imho it would make benchmark a lot easier to use if this would be done automatically.
FWIW Andrei mentioned once:

but doesn't include things like "doNotOptimizeAway" which is essential.

private void doNotOptimizeAway(T)(auto ref T t)
{
    import core.thread : getpid;
    import std.stdio : writeln;
    if(getpid() == 1) {
        writeln(*cast(char*)&t);
    }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to leave that improvement to a separate PR. The focus of this is to give us what we already have but using MonoTime and Duration rather than TickDuration.

/++
Module containing some basic benchmarking and timing functionality.

For convenience, this module publicly imports core.time.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: For consistency core.time could be a MREF...

start should not be called if the StopWatch is already running.
+/
void start() @safe nothrow @nogc
in { assert(!running); }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was a longer discussion this summer on which a majority agreed that an assert statement should have a message even if it's trivial as it greatly helps the user in figuring out what went wrong instead of the bare segfault.

stop should not be called if the StopWatch is not running.
+/
void stop() @safe nothrow @nogc
in { assert(_running); }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto about assert with a error message

result[i] = sw.peek();
}

return result;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May I ask what the rationale for removing opEquals was?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I probably removed it with the idea that it did the same thing as the defaults, since when StopWatch was originally added, it was not uncommon that you had to declare it yourself. Looking over it now, it looks like the original implementation is different from the default in that it skips comparing the _running member, therefore not treating whether the StopWatch is running as part of its comparable state. I don't know if that makes sense or not. I strongly question whether it makes any sense to compare a StopWatch in the first place.

jmdavis added 4 commits May 7, 2017 10:54
std.datetime.package has StopWatch, benchmark, comparingBenchmark, and
measureTime, all of which use TickDuration (which would be deprecated,
but it can't be deprecated as long as those functions in std.datetime
are deprecated). This commit introduces
std.datetime.stopwatch to replace those functions in std.datetime. In
order to avoid symbol conflicts, std.datetime.stopwatch will not be
publicly import in std.datetime.package until the old symbols have been
removed.

std.datetime.experimental.stopwatch contains StopWatch and benchmark
which have essentially the same APIs as the ones in
std.datetime.package, but they use MonoTime and Duration.

comparingBenchmark has not been ported to MonoTime and Duration, because
it is simply a wrapper around benchmark.

measureTime has not been ported to MonoTime and Duration, because it is
equivalent to using StopWatch with a scope(exit) statement.

The old functionality will be deprecated the major release after the new
symbols have been introduced.
Now, it includes information on std.datetime.stopwatch.
@jmdavis
Copy link
Member Author

jmdavis commented May 7, 2017

Updated based on Sebastian's comments.

Copy link
Contributor

@wilzbach wilzbach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for doing this work @jmdavis!

@wilzbach wilzbach added this to the 2.075.0 milestone May 8, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants