Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Compatibility] Added INCRBYFLOAT command #699

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

Vijay-Nirmal
Copy link
Contributor

@Vijay-Nirmal Vijay-Nirmal commented Oct 2, 2024

Adding INCRBYFLOAT command to garnet

  • Add INCRBYFLOAT command
  • Add Test cases
  • Add documentation

Question:

Do you guys have any optimal way to double to ASCII byte?

Below is a benchmark with 2 approaches.

NumOfCharInDoubleWithMathAbsRound => Same code as the PR
NumOfCharInDoubleWithDiyFp => Similar code as .Format("{0:0.####}"). Below are the links to the code I used from .dotnet runtime repo
Number.DiyFp.cs
Number.Grisu3.cs - TryRunCounted
NumOfCharInDoubleWithStringFormat => Using doubleValue.ToString("0.###############") and using buffer copy to move the value to input span
NumOfCharInDoubleWithUtf8Formatter => Using Utf8Formatter

Method Value Mean Error StdDev Gen0 Allocated
NumOfCharInDoubleWithMathAbsRound 10.23 30.55 ns 0.608 ns 0.769 ns - -
NumOfCharInDoubleWithDiyFp 10.23 51.39 ns 1.035 ns 1.346 ns - -
NumOfCharInDoubleWithStringFormat 10.23 111.70 ns 2.124 ns 1.986 ns 0.0017 32 B
NumOfCharInDoubleWithUtf8Formatter 10.23 144.58 ns 2.915 ns 2.863 ns - -
NumOfCharInDoubleWithMathAbsRound 12.023642000155785 169.63 ns 2.703 ns 2.529 ns - -
NumOfCharInDoubleWithDiyFp 12.023642000155785 50.21 ns 0.627 ns 0.586 ns - -
NumOfCharInDoubleWithStringFormat 12.023642000155785 109.51 ns 2.095 ns 2.151 ns 0.0029 56 B
NumOfCharInDoubleWithUtf8Formatter 12.023642000155785 185.39 ns 2.528 ns 2.111 ns - -
NumOfCharInDoubleWithMathAbsRound 85.98498198191919 159.88 ns 1.536 ns 1.437 ns - -
NumOfCharInDoubleWithDiyFp 85.98498198191919 51.27 ns 1.001 ns 1.112 ns - -
NumOfCharInDoubleWithStringFormat 85.98498198191919 108.07 ns 2.041 ns 1.909 ns 0.0029 56 B
NumOfCharInDoubleWithUtf8Formatter 85.98498198191919 205.70 ns 3.498 ns 3.272 ns - -
NumOfCharInDoubleWithMathAbsRound 152.3645 59.08 ns 1.211 ns 1.295 ns - -
NumOfCharInDoubleWithDiyFp 152.3645 56.91 ns 0.915 ns 0.856 ns - -
NumOfCharInDoubleWithStringFormat 152.3645 129.73 ns 2.571 ns 2.525 ns 0.0019 40 B
NumOfCharInDoubleWithUtf8Formatter 152.3645 220.38 ns 4.267 ns 4.382 ns - -
NumOfCharInDoubleWithMathAbsRound 456621336.22 78.48 ns 1.529 ns 1.761 ns - -
NumOfCharInDoubleWithDiyFp 456621336.22 45.34 ns 0.809 ns 0.757 ns - -
NumOfCharInDoubleWithStringFormat 456621336.22 135.40 ns 2.678 ns 3.387 ns 0.0024 48 B
NumOfCharInDoubleWithUtf8Formatter 456621336.22 241.70 ns 3.849 ns 3.601 ns - -
NumOfCharInDoubleWithMathAbsRound 9.874(...)2E+20 [21] 237.65 ns 3.564 ns 2.976 ns - -
NumOfCharInDoubleWithDiyFp 9.874(...)2E+20 [21] 36.29 ns 0.739 ns 0.691 ns - -
NumOfCharInDoubleWithStringFormat 9.874(...)2E+20 [21] 120.56 ns 1.948 ns 1.823 ns 0.0033 64 B
NumOfCharInDoubleWithUtf8Formatter 9.874(...)2E+20 [21] 325.66 ns 6.171 ns 5.773 ns - -

Even though the dotnet runtime approach does better in most cases in the benchmark, I have not done it as part of this PR because of 2 reasons, 1) it has lots of code and 2) for smaller numbers it always performs worse. If you guys like dotnet's approach, I can change it quickly.

Let me know if you guys have any other ideas, I can implement and compare the performance.

@badrishc
Copy link
Contributor

badrishc commented Oct 4, 2024

@badrishc
Copy link
Contributor

badrishc commented Oct 4, 2024

Or, double.TryParse(ReadOnlySpan<byte> utf8Text, out double result). This also goes from byte[] to double.

@badrishc
Copy link
Contributor

badrishc commented Oct 4, 2024

@badrishc
Copy link
Contributor

badrishc commented Oct 4, 2024

might be best to just convert the double to the ROS with a sufficiently large buffer, to know how many bytes it uses. hopefully the conversion will not need to be repeated.

@Vijay-Nirmal
Copy link
Contributor Author

Vijay-Nirmal commented Oct 4, 2024

@badrishc I have added the benchmark results with Utf8Formatter. In my benchmark, it is the slowest option. I've shared below my benchmark method for using Utf8Formatter, please let me know if I made any mistake in my benchmark. Note: We can't use exponential notation.

[Benchmark]
public byte NumOfCharInDoubleWithUtf8Formatter()
{
    Span<byte> buffer = stackalloc byte[327];  // 309 (max digits) + 1 (dot) + 17 (precision)
    Utf8Formatter.TryFormat(Value, buffer, out var bytesWritten, new StandardFormat('f', 17));
    buffer = buffer.Slice(0, bytesWritten).TrimEnd((byte)'0').TrimEnd((byte)'.');
    return buffer[0];
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants