C#的一般操作成本?

C#的一般操作成本?,c#,performance,optimization,operators,C#,Performance,Optimization,Operators,在(第601页和第602页)中,有一个“普通操作成本”表 P>基线操作整数赋值为1,然后列出java和C++的常用操作的相对时间。例如: C++ Java Integer assignment 1 1 Integer division 5 1.5 Floating point square root

在(第601页和第602页)中,有一个“普通操作成本”表

<> P>基线操作整数赋值为1,然后列出java和C++的常用操作的相对时间。例如:

                                  C++        Java
Integer assignment                1             1
Integer division                  5             1.5
Floating point square root       15             4 

问题是有没有人得到了C#的数据?我知道这些并不能帮助我解决任何问题,我只是好奇。

我实施了书中的一些测试。我电脑中的一些原始数据:

试运行#1:

证明任命00:00:00.6680000
不带参数的TestCallRoutine 00:00:00.9780000
带一个参数的TestCallRoutine 00:00:00.6580000
带两个参数的TestCallRoutine 00:00:00.9650000
证明加总00:00:00.6410000
测试减法00:00:00.9630000
睾丸增殖00:00:00.6490000
测试师00:00:00.9720000
TestFloatingPointDivision 00:00:00.6500000
TestFloatingPointSquareRoot 00:00:00.9790000
TestFloatingPointSine 00:00:00.6410000
TestFloatingPoint对数00:00:41.1410000
TestFloatingPointExp 00:00:34.6310000

试运行#2:

证明任命00:00:00.6750000
不带参数的TestCallRoutine 00:00:00.9720000
带一个参数的TestCallRoutine 00:00:00.6490000
带两个参数的TestCallRoutine 00:00:00.9750000
证明加总00:00:00.6730000
测试减法00:00:01.0300000
睾丸生殖细胞增殖00:00:00.7000000
测试师00:00:01.1120000
TestFloatingPointDivision 00:00:00.6630000
TestFloatingPointSquareRoot 00:00:00.9860000
TestFloatingPointSine 00:00:00.6530000
TestFloatingPoint对数00:00:39.1150000
TestFloatingPointExp 00:00:33.8730000

试运行#3:

证明任命00:00:00.6590000
不带参数的TestCallRoutine 00:00:00.9700000
带一个参数的TestCallRoutine 00:00:00.6680000
带有两个参数的TestCallRoutine 00:00:00.9900000
证明加总00:00:00.6720000
测试减法00:00:00.9770000
睾丸增殖00:00:00.6580000
测试师00:00:00.9930000
TestFloatingPointDivision 00:00:00.6740000
TestFloatingPointSquareRoot 00:00:01.0120000
TestFloatingPointSine 00:00:00.6700000
TestFloatingPoint对数00:00:39.1020000
TestFloatingPointExp 00:00:35.3560000

(使用Jon Skeet的微基准标记框架,使用Optimize、AMD Athlon X2 3.0ghz编译,每个基准测试10亿次,可从以下网址获得)

资料来源:

class TestBenchmark  
{  
[Benchmark]  
public static void TestIntegerAssignment()
{
int i = 1;
int j = 2;

    for (int x = 0; x < 1000000000; x++)
    {
        i = j;
    }
}

[Benchmark]
public static void TestCallRoutineWithNoParameters()
{
    for (int x = 0; x < 1000000000; x++)
    {
        TestStaticRoutine();
    }
}

[Benchmark]
public static void TestCallRoutineWithOneParameter()
{
    for (int x = 0; x < 1000000000; x++)
    {
        TestStaticRoutine2(5);
    }
}

[Benchmark]
public static void TestCallRoutineWithTwoParameters()
{
    for (int x = 0; x < 1000000000; x++)
    {
        TestStaticRoutine3(5,7);
    }
}

[Benchmark]
public static void TestIntegerAddition()
{
    int i = 1;
    int j = 2;
    int k = 3;

    for (int x = 0; x < 1000000000; x++)
    {
        i = j + k;
    }
}

[Benchmark]
public static void TestIntegerSubtraction()
{
    int i = 1;
    int j = 6;
    int k = 3;

    for (int x = 0; x < 1000000000; x++)
    {
        i = j - k;
    }
}

[Benchmark]
public static void TestIntegerMultiplication()
{
    int i = 1;
    int j = 2;
    int k = 3;

    for (int x = 0; x < 1000000000; x++)
    {
        i = j * k;
    }
}


[Benchmark]
public static void TestIntegerDivision()
{
    int i = 1;
    int j = 6;
    int k = 3;

    for (int x = 0; x < 1000000000; x++)
    {
        i = j/k;
    }
}

[Benchmark]
public static void TestFloatingPointDivision()
{
    float i = 1;
    float j = 6;
    float k = 3;

    for (int x = 0; x < 1000000000; x++)
    {
        i = j / k;
    }
}

[Benchmark]
public static void TestFloatingPointSquareRoot()
{
    double x = 1;
    float y = 6;

    for (int x2 = 0; x2 < 1000000000; x2++)
    {
        x = Math.Sqrt(6);
    }
}

[Benchmark]
public static void TestFloatingPointSine()
{
    double x = 1;
    float y = 6;

    for (int x2 = 0; x2 < 1000000000; x2++)
    {
        x = Math.Sin(y);
    }
}

[Benchmark]
public static void TestFloatingPointLogarithm()
{
    double x = 1;
    float y = 6;

    for (int x2 = 0; x2 < 1000000000; x2++)
    {
        x = Math.Log(y);
    }
}

[Benchmark]
public static void TestFloatingPointExp()
{
    double x = 1;
    float y = 6;

    for (int x2 = 0; x2 < 1000000000; x2++)
    {
        x = Math.Exp(6);
    }
}

private static void TestStaticRoutine() {

}

private static void TestStaticRoutine2(int i)
{

}

private static void TestStaticRoutine3(int i, int j)
{

}

private static class TestStaticClass
{

}
类测试基准
{  
[基准]
公共静态无效测试分配()
{
int i=1;
int j=2;
对于(int x=0;x<100000000;x++)
{
i=j;
}
}
[基准]
公共静态void TestCallRoutineWithNoParameters()
{
对于(int x=0;x<100000000;x++)
{
TestStaticRoutine();
}
}
[基准]
公共静态void TestCallRoutineWithOneParameter()
{
对于(int x=0;x<100000000;x++)
{
试验2(5);
}
}
[基准]
公共静态void TestCallRoutineWithTwoParameters()
{
对于(int x=0;x<100000000;x++)
{
TestStaticRoutine3(5,7);
}
}
[基准]
公共静态无效测试添加()
{
int i=1;
int j=2;
int k=3;
对于(int x=0;x<100000000;x++)
{
i=j+k;
}
}
[基准]
公共静态无效测试减法()
{
int i=1;
int j=6;
int k=3;
对于(int x=0;x<100000000;x++)
{
i=j-k;
}
}
[基准]
publicstaticvoid-TestIntegerMultiplication()公共静态无效测试
{
int i=1;
int j=2;
int k=3;
对于(int x=0;x<100000000;x++)
{
i=j*k;
}
}
[基准]
公共静态无效测试分部()
{
int i=1;
int j=6;
int k=3;
对于(int x=0;x<100000000;x++)
{
i=j/k;
}
}
[基准]
公共静态void TestFloatingPointDivision()
{
浮点数i=1;
浮动j=6;
浮动k=3;
对于(int x=0;x<100000000;x++)
{
i=j/k;
}
}
[基准]
公共静态void TestFloatingPointSquareRoot()
{
双x=1;
浮动y=6;
对于(int x2=0;x2<100000000;x2++)
{
x=数学Sqrt(6);
}
}
[基准]
公共静态void TestFloatingPointSine()
{
双x=1;
浮动y=6;
对于(int x2=0;x2<100000000;x2++)
{
x=数学Sin(y);
}
}
[基准]
公共静态void testfloatingpointlogum()
{
双x=1;
浮动y=6;
对于(int x2=0;x2<100000000;x2++)
{
x=数学日志(y);
}
}
[基准]
公共静态void TestFloatingPointExp()
{
双x=1;
浮动y=6;
对于(int x2=0;x2<100000000;x2++)
{
x=数学经验(6);
}
}
私有静态void TestStaticRoutine(){
}
私有静态void TestStaticRoutine2(inti)
{
}
私有静态void TestStaticRoutine3(inti,intj)
{
}
私有静态类TestStaticClass
{
}

这是一个合理的问题,但我所看到的几乎所有性能问题,尤其是Java和C中的性能问题,都归结为:

  • 太多的抽象层,以及
  • 依赖基于事件的通知样式编码
与基本操作几乎没有或根本没有关系

抽象的问题是,在工作负载变得繁重之前,它是正常的。每一层通常都会产生一个小的性能损失,并且这些损失以一种复合的方式累积。在这一点上,您开始需要变通方法。(我认为StringBuilder就是这种变通方法的一个例子。)

基于事件的通知样式编码(与通过周期性过程保持一致的简单数据结构相反)的问题是,看似简单的操作(例如将属性设置为值)可能会导致整个数据结构中的操作产生连锁反应,其效果远远超出人们的预期。