vendredi 12 avril 2019

Looking for a single timing method to test various algorithms excluding their inputs

Assume that I have several algorithms to test as follows.

void AlgoA(int x)
{
    // critical operations go here 
}

void AlgoB(int x, int y)
{
    // critical operations go here
}

First Approach

I define Timer that accepts parameterless pointer to function.

void Timer(void (*f)(), unsigned short N = 1)
{
    vector<unsigned long long> results;
    for (unsigned short i = 0; i < N; i++)
    {
        chrono::steady_clock::time_point begin = chrono::steady_clock::now();
        f();
        chrono::steady_clock::time_point end = chrono::steady_clock::now();

        unsigned long long interval = chrono::duration_cast<chrono::microseconds>(end - begin).count();
        results.push_back(interval);
        cout << "Elapsed time: " << interval << std::endl;
    }

    unsigned long long sum = 0;
    for (unsigned long long x : results)
        sum += x;
    cout << "Average: " << sum / results.size() << endl;
}

Wrappers are needed to prepare the inputs.

void DoA()
{
    int x;
    // preparing  x goes here

    AlgoA(x);
}
void DoB()
{
    int x, y;
    // preparing  x and y goes here

    AlgoB(x, y);
}
void main()
{
    Timer(DoA);
    Timer(DoB);
}

Cons: Timer also counts the time elapsed for preparing inputs.

Pros: General Timer for many algo tests.

Second Approach

I have to write 2 timers, each for an algorithm to test.

void TimerA(void (*f)(int), int x, unsigned short N = 1)
{
    vector<unsigned long long> results;
    for (unsigned short i = 0; i < N; i++)
    {
        chrono::steady_clock::time_point begin = chrono::steady_clock::now();
        f(x);
        chrono::steady_clock::time_point end = chrono::steady_clock::now();

        unsigned long long interval = chrono::duration_cast<chrono::microseconds>(end - begin).count();
        results.push_back(interval);
        cout << "Elapsed time: " << interval << std::endl;
    }

    unsigned long long sum = 0;
    for (unsigned long long x : results)
        sum += x;
    cout << "Average: " << sum / results.size() << endl;
}
void TimerB(void (*f)(int, int), int x, int y, unsigned short N = 1)
{
    vector<unsigned long long> results;
    for (unsigned short i = 0; i < N; i++)
    {
        chrono::steady_clock::time_point begin = chrono::steady_clock::now();
        f(x, y);
        chrono::steady_clock::time_point end = chrono::steady_clock::now();

        unsigned long long interval = chrono::duration_cast<chrono::microseconds>(end - begin).count();
        results.push_back(interval);
        cout << "Elapsed time: " << interval << std::endl;
    }

    unsigned long long sum = 0;
    for (unsigned long long x : results)
        sum += x;
    cout << "Average: " << sum / results.size() << endl;
}



void main()
{
    int x;
    // preparing x goes here.
    TimerA(AlgoA, x);

    int y;
    // preparing y goes here.
    TimerB(AlgoB, x, y);
}

Pros: Timers count only the critical operations.

Cons: Multiple timers, each for an algo to test.

Question

Is there any way to just create a single Timer but it must not count the time needed to prepare the inputs?

Aucun commentaire:

Enregistrer un commentaire