Как измерить прошедшее время в C # и C ++ - PullRequest
17 голосов
/ 14 октября 2011

У меня есть простой код на C # и C ++, который вычисляет сумму продуктов с точками.

Код C #:

using System;

namespace DotPerfTestCS
{
    class Program
    {
        struct Point3D
        {
            public double X, Y, Z;

            public Point3D(double x, double y, double z)
            {
                X = x;
                Y = y;
                Z = z;
            }
        }

        static void RunTest()
        {
            unchecked
            {
                const int numPoints = 100000;
                const int numIters = 100000000;

                Point3D[] pts = new Point3D[numPoints];
                for (int i = 0; i < numPoints; i++) pts[i] = new Point3D(i, i + 1, i + 2);

                var begin = DateTime.Now;
                double sum = 0.0;
                var u = new Point3D(1, 2, 3);
                for (int i = 0; i < numIters; i++)
                {
                    var v = pts[i % numPoints];
                    sum += u.X * v.X + u.Y * v.Y + u.Z * v.Z;
                }
                var end = DateTime.Now;
                Console.WriteLine("Sum: {0} Time elapsed: {1} ms", sum, (end - begin).TotalMilliseconds);
            }
        }

        static void Main(string[] args)
        {
            for (int i = 0; i < 5; i++) RunTest();
        }
    }
}

и C ++ -

#include <iostream>
#include <vector>
#include <time.h>

using namespace std;

typedef struct point3d
{
    double x, y, z;

    point3d(double x, double y, double z)
    {
        this->x = x;
        this->y = y;
        this->z = z;
    }
} point3d_t;

double diffclock(clock_t clock1,clock_t clock2)
{
    double diffticks=clock1-clock2;
    double diffms=(diffticks*10)/CLOCKS_PER_SEC;
    return diffms;
}

void runTest()
{
    const int numPoints = 100000;
    const int numIters = 100000000;

    vector<point3d_t> pts;
    for (int i = 0; i < numPoints; i++) pts.push_back(point3d_t(i, i + 1, i + 2));

    auto begin = clock();
    double sum = 0.0, dum = 0.0;
    point3d_t u(1, 2, 3);
    for (int i = 0; i < numIters; i++) 
    {
        point3d_t v = pts[i % numPoints];
        sum += u.x * v.x + u.y * v.y + u.z * v.z;
    }
    auto end = clock();
    cout << "Sum: " << sum << " Time elapsed: " << double(diffclock(end,begin)) << " ms" << endl;

}

int main()
{
    for (int i = 0; i < 5; i++) runTest();
    return 0;
}

Версия C # (Выпуск x86 с оптимизацией, x64 еще медленнее) выводит

Sum: 30000500000000 Time elapsed: 551.0299 ms 
Sum: 30000500000000 Time elapsed: 551.0315 ms 
Sum: 30000500000000 Time elapsed: 552.0294 ms
Sum: 30000500000000 Time elapsed: 551.0316 ms 
Sum: 30000500000000 Time elapsed: 550.0315 ms

в то время как C ++ (настройки сборки выпуска VS2010 по умолчанию) выдает

Sum: 3.00005e+013 Time elapsed: 4.27 ms
Sum: 3.00005e+013 Time elapsed: 4.27 ms
Sum: 3.00005e+013 Time elapsed: 4.25 ms
Sum: 3.00005e+013 Time elapsed: 4.25 ms
Sum: 3.00005e+013 Time elapsed: 4.25 ms

Теперь я ожидаю, что код C # будет немного медленнее. Но в 130 раз медленнее кажется мне слишком много. Может кто-нибудь объяснить мне, что здесь происходит?

EDIT

Я не программист на C ++ и просто взял код diffclock где-то в интернете, не проверяя, действительно ли он корректен.

При использовании std :: difftime результаты C ++ равны

Sum: 3.00005e+013 Time elapsed: 457 ms
Sum: 3.00005e+013 Time elapsed: 452 ms
Sum: 3.00005e+013 Time elapsed: 451 ms
Sum: 3.00005e+013 Time elapsed: 451 ms
Sum: 3.00005e+013 Time elapsed: 451 ms

что кажется правильным.

Ответы [ 3 ]

13 голосов
/ 14 октября 2011

Ваш код diffclock неправильный.

Если вы измените свой код C ++, чтобы использовать std::clock и std::difftime, то будет отображаться фактическое время выполнения:

#include <iostream>
#include <vector>
#include <ctime>

using namespace std;

typedef struct point3d
{
    double x, y, z;

    point3d(double x, double y, double z)
    {
        this->x = x;
        this->y = y;
        this->z = z;
    }
} point3d_t;

void runTest()
{
    const int numPoints = 100000;
    const int numIters = 100000000;

    vector<point3d_t> pts;
    for (int i = 0; i < numPoints; i++) pts.push_back(point3d_t(i, i + 1, i + 2));

    auto begin = clock();
    double sum = 0.0, dum = 0.0;
    point3d_t u(1, 2, 3);
    for (int i = 0; i < numIters; i++) 
    {
        point3d_t v = pts[i % numPoints];
        sum += u.x * v.x + u.y * v.y + u.z * v.z;
    }
    auto end = clock();
    cout << "Sum: " << sum << " Time elapsed: " << double(std::difftime(end,begin)) << " ms" << endl;

}

int main()
{
    for (int i = 0; i < 5; i++) runTest();
    return 0;
}

Результаты:

Sum: 3.00005e+013 Time elapsed: 346 ms
Sum: 3.00005e+013 Time elapsed: 344 ms
Sum: 3.00005e+013 Time elapsed: 346 ms
Sum: 3.00005e+013 Time elapsed: 347 ms
Sum: 3.00005e+013 Time elapsed: 347 ms

То есть приложение работает с оптимизацией режима выпуска по умолчанию за пределами vs2010.

EDIT

Как отмечали другие, в C ++ использование clock () - не самый точный способ измерения времени функции (как в C #, Stopwatch лучше, чем DateTime).

Если вы используете Windows, вы всегда можете использовать QueryPerformanceCounter для синхронизации с высоким разрешением.

6 голосов
/ 14 октября 2011

Я полагаю, вы найдете, что ваша реализация diffclock дает децисекунды, а не миллисекунды (при условии, что CLOCKS_PER_SECOND назван точно). Исправляя это, реализация C # работает примерно на 30% медленнее, что кажется целесообразным.

0 голосов
/ 14 октября 2011

Самой очевидной причиной будет JIT, но как только будет подтверждено, что она не является причиной, у меня есть другое объяснение.

"new Point3D" встречается 100000 раз.Это 100000 распределений кучи, которые затем освобождаются.В версии C ++ вектор также основан на куче, что означает, что при его росте происходит перераспределение.Но когда вектор растет, он увеличивается намного больше, чем на один point3d_t каждый раз.Я ожидаю только около 30 вызовов realloc в версии C ++.

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