buybackoff / 1brc

1BRC in .NET among fastest on Linux
https://hotforknowledge.com/2024/01/13/1brc-in-dotnet-among-fastest-on-linux-my-optimization-journey/
MIT License
437 stars 43 forks source link

Implement ISpanFormattable on Summary #8

Closed sonnemaf closed 8 months ago

sonnemaf commented 8 months ago

Hi,

I think you can win something by implementing ISpanFormattable on Summary. This will make the string interpolation in Console.Write($"{pair.Name}={pair.Value}") run faster. You avoid the ToString() method.

You can try this using this code. It was faster on my (slow) computer.

public struct Summary : ISpanFormattable {

    public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider) {
        return destination.TryWrite($"{Min / 10.0:N1}/{Average / 10.0:N1}/{Max / 10.0:N1}", out charsWritten);
    }

    public string ToString(string? format, IFormatProvider? formatProvider) {
        return ToString();
    }

If it works you can even gain more performance by reimplementing the TryFormat method without the use of the TryWrite extensionmethod. It quite a lot of work but might work.

Regards,

Fons

buybackoff commented 8 months ago

Oh, do you realize that if everything other than ProcessChunk was exactly zero then the difference would be less than the noise on my very stable dedicated benchmarking machine!?

sonnemaf commented 8 months ago

Are you saying that the Console.Write() is free? Can't imagine that.

buybackoff commented 8 months ago

It takes ~ 15-20 msec. Well, my benchmark resolution is better than that, I will admit that. Will see if the impact is visible.

buybackoff commented 8 months ago

Actually I already use that locally, not committed yet. I thought you've implemented Utf8 formatting to a Span<byte>.

image

buybackoff commented 8 months ago

I actually like this because it's the right approach. Even if there is not difference in performance. Thank you!

image

image