Jump to page: 1 2 3
Thread overview
July 04

Dave's Garage is hosting a race to find the fastest among 45 programming languages. I just watched the first episode covering Pascal, Delphi and Ada. There is currently one contribution in D by Eagerestwolf. If you can make it faster or want to submit a parallel version, I think they still accept contributions.

I don't know when the episode on D will be made, and it might be interesting if multiple solutions using different styles are available. Anyway, tweaks will be accepted until a final comparison in the last episode.

-- Bastiaan.

July 04

On Sunday, 4 July 2021 at 15:31:31 UTC, Bastiaan Veelo wrote:

>

...

Decided to give it a go. Faithful but is slightly more D-ish https://github.com/PlummersSoftwareLLC/Primes/pull/292

July 04

On Sunday, 4 July 2021 at 22:35:44 UTC, SealabJaster wrote:

>

On Sunday, 4 July 2021 at 15:31:31 UTC, Bastiaan Veelo wrote:

>

...

Decided to give it a go. Faithful but is slightly more D-ish https://github.com/PlummersSoftwareLLC/Primes/pull/292

The more I think about it though, maybe this should've just been an improvement over solution 1, instead of putting it as a second solution.

July 13

On Sunday, 4 July 2021 at 22:35:44 UTC, SealabJaster wrote:

>

On Sunday, 4 July 2021 at 15:31:31 UTC, Bastiaan Veelo wrote:

>

...

Decided to give it a go. Faithful but is slightly more D-ish https://github.com/PlummersSoftwareLLC/Primes/pull/292

Merged here:
https://github.com/PlummersSoftwareLLC/Primes/tree/drag-race/PrimeD/solution_2

I like it! A few points:

  1. The output in the readme shows Valid: false, which worries me. I didn't try your solution myself yet.
  2. Not sure if this was clearly stated in the rules, but he says that the sieve size must be a run time value. I hope this doesn't disqualify your solution.

Further some nit-picks, feel free to ignore:

  1. Line 23 // it also allows D to write more "file-portable" code. Not sure what you mean by this. Worth noting however is that the import only happens iff the template is instantiated, which is nice.
  2. Line 38: Did you mean to leave (citation needed) in there?
  3. printResults can be made @safe by means of a nested @trusted wrapper (ref):
    // If not called from multiple threads, this can be trusted.
    static File trustedStderr() @trusted
    {
        return stderr;
    }

Out of curiosity, do you know how your solution compares with the first one performance wise, roughly?

Thanks for your submission!

-- Bastiaan.

July 13

On Tuesday, 13 July 2021 at 19:06:12 UTC, Bastiaan Veelo wrote:

>
// If not called from multiple threads, this can be trusted.

I.e., it can't be trusted. When a function needs a comment that explains how to call it safely, then it's an @system function.

July 13

On Tuesday, 13 July 2021 at 19:45:48 UTC, ag0aep6g wrote:

>

On Tuesday, 13 July 2021 at 19:06:12 UTC, Bastiaan Veelo wrote:

>
// If not called from multiple threads, this can be trusted.

I.e., it can't be trusted. When a function needs a comment that explains how to call it safely, then it's an @system function.

Then printResults can't be trusted either. Or change the comment s/If/Since/?

July 13

On Tuesday, 13 July 2021 at 19:06:12 UTC, Bastiaan Veelo wrote:

>
  1. Not sure if this was clearly stated in the rules, but he says that the sieve size must be a run time value. I hope this doesn't disqualify your solution.

Not disqualified, but rendered unfaithful.

IIRC unfaithful solutions can still be discussed in the video and therefore be interesting, but the benchmark is about faithful solutions...

--Bastiaan.

July 13

On Tuesday, 13 July 2021 at 19:06:12 UTC, Bastiaan Veelo wrote:

>
  1. The output in the readme shows Valid: false, which worries me. I didn't try your solution myself yet.

Oop. So what happened there is, I updated the README while validateResults was broken, and completely forgot to fix the README after fixing validateResults.

I can assure you it shows Valid: true now!

>
  1. Not sure if this was clearly stated in the rules, but he says that the sieve size must be a run time value. I hope this doesn't disqualify your solution.

oooh. It's easy to read over but it does seem to say that:

>

The sieve size and corresponding prime candidate memory buffer (or language equivalent) are set/allocated dynamically at runtime. The size of the memory buffer must correspond to the size of the sieve.

It'll mean that the solution can't be marked as faithful: yes anymore, I'll open a PR soon to make sure that's fixed.

Or maybe I'll update the code slightly to allow both a runtime and compile-time set sieve size >:3

While the Sieve does do the computations at runtime, the sieve size is a compile-time constant, and the buffer is static (technically one could argue that it is dynamically allocated due to being in a class >:D ).

>
  1. Line 23 // it also allows D to write more "file-portable" code. Not sure what you mean by this. Worth noting however is that the import only happens iff the template is instantiated, which is nice.

Basically, if you use scoped imports it tends to be a lot easier to move a piece of code between different files. A lot of the time you can get away with a simple cut+paste and it can just work.

Hence, portable across files.

>
  1. Line 38: Did you mean to leave (citation needed) in there?

Perhaps ;)

>
  1. printResults can be made @safe by means of a nested @trusted wrapper (ref):
    // If not called from multiple threads, this can be trusted.
    static File trustedStderr() @trusted
    {
        return stderr;
    }

It really doesn't feel right to do that. I didn't use the @trusted lambda hack for a reason.

>

Out of curiosity, do you know how your solution compares with the first one performance wise, roughly?

[1] is for the first solution, and [2] is for the second one.

Because the second solution has some compile-time things going on, it's doing a fair amount less work: not needing to allocate the list of sieve sizes; validateResults not needing to do a lookup; one less level of indirection because it uses a static array; etc.

I also set some compiler flags in dub.sdl, which doesn't actually seem to change solution_1 all that much if I apply the same flags to it.

As I mentioned in the PR as well, LDC is capable of inlining ranges, so even though this code is more idiomatic, it compiles like it was written in a more traditional C style.

[1] https://pastebin.com/Q0UxibTi
[2] https://pastebin.com/tmXDwejS

July 13

On Tuesday, 13 July 2021 at 21:02:55 UTC, SealabJaster wrote:

>

I can assure you it shows Valid: true now!

Phew! :-)

>

Or maybe I'll update the code slightly to allow both a runtime and compile-time set sieve size >:3

That would be nice.

>

While the Sieve does do the computations at runtime, the sieve size is a compile-time constant, and the buffer is static (technically one could argue that it is dynamically allocated due to being in a class >:D ).

Heh yes. Also, he said something like “as if you would write an API”. I like templated APIs…

I saw two comments regarding dynamic sieve size. One of them was an entire stack-based implementation, to which he responded not seeing a problem with that. Another suggested using alloca.

> >
  1. Line 23 // it also allows D to write more "file-portable" code. Not sure what you mean by this. Worth noting however is that the import only happens iff the template is instantiated, which is nice.

Basically, if you use scoped imports it tends to be a lot easier to move a piece of code between different files. A lot of the time you can get away with a simple cut+paste and it can just work.

Agreed. Thanks.

> >

Out of curiosity, do you know how your solution compares with the first one performance wise, roughly?

[1] is for the first solution, and [2] is for the second one.

[….]

>

[1] https://pastebin.com/Q0UxibTi
[2] https://pastebin.com/tmXDwejS

Those are nice improvements! Glad you took the time.

— Bastiaan.

July 13

On Tuesday, 13 July 2021 at 21:02:55 UTC, SealabJaster wrote:

>

Because the second solution has some compile-time things going on, it's doing a fair amount less work: not needing to allocate the list of sieve sizes; validateResults not needing to do a lookup; one less level of indirection because it uses a static array; etc.

Some corrections:

>

not needing to allocate the list of sieve sizes

This actually doesn't matter since there's no need to do so until the primes are calculated, so time taken doesn't need to be measured.

>

validateResults not needing to do a lookup

This function isn't part of the measurement either.

« First   ‹ Prev
1 2 3