CodeConverter icon indicating copy to clipboard operation
CodeConverter copied to clipboard

VB -> C#: Optimize Double(/Decimal)-to-Integer conversion

Open tats-u opened this issue 1 year ago • 4 comments

VB.Net input code

Imports System

Public Class A
    Public Shared Sub Main()
        Dim foo = 0.6
        Dim bar = CInt(Math.Truncate(foo))
        Dim baz = CInt(Math.Ceiling(foo))
        Console.WriteLine(bar)
        Console.WriteLine(baz)
    End Sub
End Class

Erroneous output

using System;

public partial class A
{
    public static void Main()
    {
        double foo = 0.6d;
        int bar = (int)Math.Round(Math.Truncate(foo));
        int baz = (int)Math.Round(Math.Ceiling(foo));
        Console.WriteLine(bar);
        Console.WriteLine(baz);
    }
}

Extra verbose Math.Round

Expected output

using System;

public partial class A
{
    public static void Main()
    {
        double foo = 0.6d;
        int bar = (int)foo;
        int baz = (int)Math.Ceiling(foo);
        Console.WriteLine(bar);
        Console.WriteLine(baz);
    }
}

Decimal is not optimized by the latest VB compiler but I think it can be.

CInt(Decimal)System.Convert.ToInt32 (similar as (int)Math.Round)

Details

  • Product in use: online
  • Version in use: e.g. 5.6.3 or a commit hash (if it's a 3rd party tool using this library, try one of the above)
  • Did you see it working in a previous version, which? No
  • Any other relevant information to the issue, or your interest in contributing a fix.

tats-u avatar Jun 27 '23 23:06 tats-u

Just to make sure I understand, I assume you mean that methods already returning integers (floor, ceiling, truncate, round) don't need an additional round to be added?

GrahamTheCoder avatar Jun 28 '23 07:06 GrahamTheCoder

Those methods return values whose types are same as input. VB does bankers' rounding but C# does truncation when converting floating points to integers.

tats-u avatar Jun 28 '23 08:06 tats-u

https://sharplab.io/#v2:DYLgbgRgNAJiDUAfAkgWwA4HsBOAXAzgAQDKAnvrgKaoCwAUPQAoCuEwAlgMaEDCwAhviIBBeoXGEWbLiQAW/bJRglWhALL92AOwAUASjESjAEXapCAM0yZCAXkIAGAHQA2Q0fGnzEBXd7ItXB0NXFknABVsZi1OfiodK0w9AzoPCS9CHwAvPx4AoJCwnkp2Di0AcwTrZPcPHkwtfExgSicAdWx2KgAZbUodH2wUtPF6xubWjq7KXq1+7OGJAFEtZWJWehXlPkF8IA==

using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue | DebuggableAttribute.DebuggingModes.DisableOptimizations)]
[assembly: AssemblyVersion("0.0.0.0")]

public class A
{
    public static void Main()
    {
        double num = 0.6;
        checked
        {
            int value = (int)num;
            int value2 = (int)Math.Ceiling(num);
            Console.WriteLine(value);
            Console.WriteLine(value2);
        }
    }
}

https://learn.microsoft.com/en-us/dotnet/api/system.math.truncate?view=net-7.0

Starting with Visual Basic 15.8, the performance of Double-to-integer conversion is optimized if you pass the value returned by the Truncate method to the any of the integral conversion functions, or if the Double value returned by Truncate is automatically converted to an integer with Option Strict set to Off. This optimization allows code to run faster -- up to twice as fast for code that does a large number of conversions to integer types. The following example illustrates such an optimized conversion:

tats-u avatar Jun 28 '23 14:06 tats-u

https://sharplab.io/#v2:DYLgbgRgPgkgtgBwPYCcAuBnABAZQJ4ZoCmcAsAFAUAKArhMAJYDGWAwsAIYbYCCFWArLXrNcACw4oiAE1x0sAWQ4MAdgAoAlP0E6AIgzhYAZkiRYAvFgAMAOgBs2nQP2GIki2xgq0apWjE2ACooNCpMHMRqJkgaWuROgi5YbgBeHqxePn4BrEQMjCoA5lGmsY5OrEgqGEjARDYA6igMxAAyqkRqbihxCQKV1bX1TS1E7Sqdqb2CAKIqsjh0FHOy7FwYQA==

VB compiler (LocalRewriter) in Roslyn has already done this optimization for Double. However, it has no plan for Decimal in the future.

https://sourceroslyn.io/#Microsoft.CodeAnalysis.VisualBasic/Lowering/LocalRewriter/LocalRewriter_Conversion.vb,921944f13b116c29,references

tats-u avatar Apr 10 '24 12:04 tats-u