Стоимость обычных операций для C #? - PullRequest
7 голосов
/ 16 мая 2009

В 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 ]

10 голосов
/ 16 мая 2009

Я реализовал некоторые тесты из книги. Некоторые необработанные данные с моего компьютера:

Тестовый прогон № 1:

TestIntegerAssignment 00: 00: 00.6680000
TestCallRoutineWithNoParameters 00: 00: 00.9780000
TestCallRoutineWithOneParameter 00: 00: 00.6580000
TestCallRoutineWithTwoParameters 00: 00: 00.9650000
TestIntegerAddition 00: 00: 00.6410000
TestIntegerSubtraction 00: 00: 00.9630000
TestIntegerMultiplication 00: 00: 00.6490000
TestIntegerDivision 00: 00: 00.9720000
TestFloatingPointDivision 00: 00: 00.6500000
TestFloatingPointSquareRoot 00: 00: 00.9790000
TestFloatingPointSine 00: 00: 00.6410000
TestFloatingPointLogarithm 00: 00: 41.1410000
TestFloatingPointExp 00: 00: 34.6310000

Тестовый прогон № 2:

TestIntegerAssignment 00: 00: 00.6750000
TestCallRoutineWithNoParameters 00: 00: 00.9720000
TestCallRoutineWithOneParameter 00: 00: 00.6490000
TestCallRoutineWithTwoParameters 00: 00: 00.9750000
TestIntegerAddition 00: 00: 00.6730000
TestIntegerSubtraction 00: 00: 01.0300000
TestIntegerMultiplication 00: 00: 00.7000000
TestIntegerDivision 00: 00: 01.1120000
TestFloatingPointDivision 00: 00: 00.6630000
TestFloatingPointSquareRoot 00: 00: 00.9860000
TestFloatingPointSine 00: 00: 00.6530000
TestFloatingPointLogarithm 00: 00: 39.1150000
TestFloatingPointExp 00: 00: 33.8730000

Тестовый прогон № 3:

TestIntegerAssignment 00: 00: 00.6590000
TestCallRoutineWithNoParameters 00: 00: 00.9700000
TestCallRoutineWithOneParameter 00: 00: 00.6680000
TestCallRoutineWithTwoParameters 00: 00: 00.9900000
TestIntegerAddition 00: 00: 00.6720000
TestIntegerSubtraction 00: 00: 00.9770000
TestIntegerMultiplication 00: 00: 00.6580000
TestIntegerDivision 00: 00: 00.9930000
TestFloatingPointDivision 00: 00: 00.6740000
TestFloatingPointSquareRoot 00: 00: 01.0120000
TestFloatingPointSine 00: 00: 00.6700000
TestFloatingPointLogarithm 00: 00: 39.1020000
TestFloatingPointExp 00: 00: 35.3560000

(1 миллиард тестов на эталонный тест, скомпилированный с Optimize, AMD Athlon X2 3.0 ГГц, с использованием инфраструктуры микробенчмаркинга 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
{

}
4 голосов
/ 22 мая 2009

Прямо от источника, Знайте, сколько стоит .

IIRC Rico Mariani использовал относительные показатели, которые вы просили в своем блоге , но я больше не могу его найти (хотя я знаю, что это в одной из двух закладок "dev" ... )

2 голосов
/ 16 мая 2009

Это разумный вопрос, но почти все проблемы с производительностью, которые я видел, особенно в Java и C #, сводились к:

  • слишком много слоев абстракции и
  • опора на кодирование в стиле уведомлений на основе событий.

, которые не имеют ничего общего с основными операциями.

Проблема с абстракцией в том, что до тех пор, пока рабочая нагрузка не станет большой, это нормально. Каждый уровень обычно требует небольшого снижения производительности, и они накапливаются сложным образом. На этом этапе вы начинаете нуждаться в обходных решениях. (Я думаю, что StringBuilder является примером такого обходного пути.)

Проблема с кодированием в стиле уведомлений на основе событий (в отличие от более простых структур данных, поддерживаемых периодическим процессом) состоит в том, что то, что может показаться простым действием, например установление свойства в значение, может привести к пульсации эффект от действий по всей структуре данных, выполняющий гораздо больше, чем можно было ожидать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...