为什么C#执行的Math.sqrt()不是更慢VB.NET? [英] Why does C# execute Math.Sqrt() more slowly than VB.NET?

查看:183
本文介绍了为什么C#执行的Math.sqrt()不是更慢VB.NET?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景

在运行基准测试今天上午,我和同事们发现了关于C#code与VB.NET code性能的一些奇怪的事情。

我们开始了比较,C#与德尔福棱镜计算素数,发现棱镜约30%的速度。我想通codeGear优化code更产生IL时(即 exe文件约两倍大,C#的,并有各种不同的白细胞介素在里面。)

我决定写在VB.NET测试和,假设微软的编译器最终会写入本质上是相同的IL为每种语言。但是,结果出现了更令人震惊:的code跑了三倍多慢于C#比VB使用相同的操作

生成的IL是不同的,但不是非常所以,我不够好,在阅读它,了解差异。

基准

我已经包含了code每个以下。在我的机器,VB发现在约 6.36 秒348513素数。 C#中发现的素数的 21.76 秒数相同。

电脑规格和注意事项

  • 在英特尔酷睿2四核6600 @ 2.4GHz的

每一个机器,我已经在那里测试是在C#和VB.NET的基准测试结果明显的区别。

两者的控制台应用程序进行编译发布模式,但在其他方面没有项目设置从由Visual Studio 2008中生成的默认值改变。

VB.NET code

进口System.Diagnostics程序 模块模块1     私人临时方式列表(中的Int32)     私人SW作为秒表     私人totalSeconds作为双     副主()         serialCalc()     结束小组     私人小组serialCalc()         临时=新的列表(中的Int32)()         SW = Stopwatch.StartNew()         对于我作为的Int32 = 2至5000000             testIfPrimeSerial㈠         下一个         sw.Stop()         totalSeconds = sw.Elapsed.TotalSeconds         Console.WriteLine(的String.Format({0}秒过去了。totalSeconds))         Console.WriteLine(的String.Format({0}找到素数,temp.Count))         Console.ReadKey()     结束小组     私人小组testIfPrimeSerial(BYVAL suspectPrime作为的Int32)         对于我作为的Int32 = 2至的Math.sqrt(suspectPrime)             如果(suspectPrime MOD I = 0)然后                 退出小组             结束如果         下一个         temp.Add(suspectPrime)     结束小组 前端模块

C#code

 使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;
使用System.Diagnostics程序;

命名空间FindPrimesCSharp {
    类节目{
        名单<的Int32>临时=新的名单,其中,的Int32>();
        秒表SW;
        双totalSeconds;


        静态无效的主要(字串[] args){

            新计划()serialCalc()。

        }


        私人无效serialCalc(){
            临时=新的名单,其中,的Int32>();
            SW = Stopwatch.StartNew();
            为(我的Int32 = 2; I< = 5000000;我++){
                testIfPrimeSerial(ⅰ);
            }
            sw.Stop();
            totalSeconds = sw.Elapsed.TotalSeconds;
            Console.WriteLine(的String.Format({0}秒过去了。totalSeconds));
            Console.WriteLine(的String.Format({0}找到素数,temp.Count));
            Console.ReadKey();
        }

        私人无效testIfPrimeSerial(的Int32 suspectPrime){
            为(我的Int32 = 2; I< =的Math.sqrt(suspectPrime);我++){
                如果(suspectPrime%我== 0)
                    返回;
            }
            temp.Add(suspectPrime);
        }

    }
}
 

为什么是C#的执行中的Math.sqrt()比VB.NET慢?

<类=h2_linDIV>解决方案

C#的实现是重新计算的Math.sqrt(suspectPrime)通过每一次循环,而只有VB计算它在循环的开始。这仅仅是由于控制结构的性质。在C#中,只是一个花哨的,而循环,而在VB中它是一个独立的结构。

使用这个循环将甚至达到了比分:

 的Int32开方=(INT)的Math.sqrt(suspectPrime)
        为(我的Int32 = 2; I&LT; =开方;我++){
            如果(suspectPrime%我== 0)
                返回;
        }
 

Background

While running benchmark tests this morning, my colleagues and I discovered some strange things concerning performance of C# code vs. VB.NET code.

We started out comparing C# vs. Delphi Prism calculating prime numbers, and found that Prism was about 30% faster. I figured CodeGear optimized code more when generating IL (the exe was about twice as big as C#'s and had all sorts of different IL in it.)

I decided to write a test in VB.NET as well, assuming that Microsoft's compilers would end up writing essentially the same IL for each language. However, the result there was more shocking: the code ran more than three times slower on C# than VB with the same operation!

The generated IL was different, but not extremely so, and I'm not good enough at reading it to understand the differences.

Benchmarks

I've included the code for each below. On my machine, VB finds 348513 primes in about 6.36 seconds. C# finds the same number of primes in 21.76 seconds.

Computer Specs and Notes

  • Intel Core 2 Quad 6600 @ 2.4Ghz

Every machine I've tested on there is a noticeable difference in the benchmark results between C# and VB.NET.

Both of the console applications were compiled in Release mode, but otherwise no project settings were changed from the defaults generated by Visual Studio 2008.

VB.NET code

Imports System.Diagnostics

Module Module1

    Private temp As List(Of Int32)
    Private sw As Stopwatch
    Private totalSeconds As Double

    Sub Main()
        serialCalc()
    End Sub

    Private Sub serialCalc()
        temp = New List(Of Int32)()
        sw = Stopwatch.StartNew()
        For i As Int32 = 2 To 5000000
            testIfPrimeSerial(i)
        Next
        sw.Stop()
        totalSeconds = sw.Elapsed.TotalSeconds
        Console.WriteLine(String.Format("{0} seconds elapsed.", totalSeconds))
        Console.WriteLine(String.Format("{0} primes found.", temp.Count))
        Console.ReadKey()
    End Sub

    Private Sub testIfPrimeSerial(ByVal suspectPrime As Int32)
        For i As Int32 = 2 To Math.Sqrt(suspectPrime)
            If (suspectPrime Mod i = 0) Then
                Exit Sub
            End If
        Next
        temp.Add(suspectPrime)
    End Sub

End Module

C# Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace FindPrimesCSharp {
    class Program {
        List<Int32> temp = new List<Int32>();
        Stopwatch sw;
        double totalSeconds;


        static void Main(string[] args) {

            new Program().serialCalc();

        }


        private void serialCalc() {
            temp = new List<Int32>();
            sw = Stopwatch.StartNew();
            for (Int32 i = 2; i <= 5000000; i++) {
                testIfPrimeSerial(i);
            }
            sw.Stop();
            totalSeconds = sw.Elapsed.TotalSeconds;
            Console.WriteLine(string.Format("{0} seconds elapsed.", totalSeconds));
            Console.WriteLine(string.Format("{0} primes found.", temp.Count));
            Console.ReadKey();
        }

        private void testIfPrimeSerial(Int32 suspectPrime) {
            for (Int32 i = 2; i <= Math.Sqrt(suspectPrime); i++) {
                if (suspectPrime % i == 0)
                    return;
            }
            temp.Add(suspectPrime);
        }

    }
}

Why is C#'s execution of Math.Sqrt() slower than VB.NET?

解决方案

The C# implementation is recalculating Math.Sqrt(suspectPrime) each time through the loop, while VB only calculates it at the beginning of the loop. This is just due to the nature of the control structure. In C#, for is just a fancy while loop, while in VB it's a separate construct.

Using this loop will even up the score:

        Int32 sqrt = (int)Math.Sqrt(suspectPrime)
        for (Int32 i = 2; i <= sqrt; i++) { 
            if (suspectPrime % i == 0) 
                return; 
        }

这篇关于为什么C#执行的Math.sqrt()不是更慢VB.NET?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆