代码之家  ›  专栏  ›  技术社区  ›  Ian G

C的公共运营成本

  •  7
  • Ian G  · 技术社区  · 16 年前

    Code Complete 2 (第601页和602页)有一个“共同经营成本”表。

    基线运算整数赋值为值1,然后为Java和C++列出共同操作的相对时间。例如:

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

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

    3 回复  |  直到 16 年前
        1
  •  4
  •   peterchen    16 年前

    直接从源头, Know what things cost .

    里科·马里亚尼与你要求的有相对的标准。 on his blog 但是,我再也找不到了(我知道它在twohudnred的“dev”书签中…)

        2
  •  10
  •   Robert Venables    16 年前

    我实现了书中的一些测试。来自我的计算机的一些原始数据:

    试运行第1号:

    测试分配00:00:00.6680000
    无参数的测试程序00:00:00.9780000
    使用一个参数00:00:00.6580000进行测试
    两个参数的测试程序00:00:00.9650000
    测试添加00:00:00.6410000
    测试减法00:00:00.9630000
    测试细菌繁殖00:00:00.6490000
    鉴定师00:00:00.9720000
    测试浮点划分00:00:00.6500000
    测试浮点平方根00:00:00.9790000
    测试浮点sine 00:00:00.6410000
    测试浮点对数00:00:41.1410000
    测试浮动点xp 00:00:34.6310000

    试运行第2号:

    测试分配00:00:00.6750000
    无参数的测试程序00:00:00.9720000
    使用一个参数00:00:00.6490000进行测试
    用两个参数00:00:00.9750000进行测试
    测试添加00:00:00.6730000
    测试减去00:00:01.0300000
    睾丸生殖学00:00:00.7000000
    鉴定师00:00:01.1120000
    测试浮点区00:00:00.6630000
    测试浮点平方根00:00:00.9860000
    测试浮点sine 00:00:00.6530000
    测试浮点对数00:00:39.1150000
    测试浮动指针xp 00:00:33.8730000

    试运行第3号:

    测试分配00:00:00.6590000
    无参数的测试程序00:00:00.9700000
    使用一个参数00:00:00.6680000进行测试
    用两个参数00:00:00.9900000进行测试
    测试添加00:00:00.6720000
    测试减去00:00:00.9770000
    睾丸生殖学00:00:00.6580000
    鉴定师00:00:00.9930000
    测试浮点划分00:00:00.6740000
    测试浮点平方根00:00:01.0120000
    测试浮点sine 00:00:00.6700000
    测试浮点对数00:00:39.1020000
    测试浮动指针xp 00:00:35.3560000

    (每个基准测试10亿次,用optimize编译,AMD Athlon x2 3.0GHz,使用jon skeet的微基准标记框架,可在 http://www.yoda.arachsys.com/csharp/benchmark.html )

    来源:

    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
    {
    
    }
    
        3
  •  1
  •   Mike Dunlavey    16 年前

    这是一个合理的问题,但是几乎所有我见过的性能问题,特别是在Java和C中,都归结为:

    • 抽象层太多,以及
    • 依赖于基于事件的通知样式编码。

    与基本操作几乎无关。

    抽象的问题是,在工作量变大之前,它是很好的。每一层通常要求一个小的性能惩罚,并且这些惩罚以复合的方式累积。在那一点上,你开始需要解决方法。(我认为StringBuilder就是这种变通方法的一个例子。)

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