Hi all!

I have some new results regarding the Isolate/Context performance benchmarks. I re-wrote the test using the ideas Kent suggested in the previous letter. It seems that the more 'stuff' you do in those functions using Isolate and/or Context the less the performance gap between the two solutions will be.
A sample run with 10 test:

doStuff() tests:
        Own Isolate:
                Mean: 36.41 ms; Deviation: 0.28 ms
        Default Isolate:
                Mean: 5.57 ms; Deviation: 0.04 ms
doMoreStuff() tests:
        Own Isolate:
                Mean: 99.32 ms; Deviation: 1.47 ms
        Default Isolate:
                Mean: 64.27 ms; Deviation: 0.70 ms
executeScript() tests:
        Own Isolate:
                Mean: 1523.72 ms; Deviation: 8.02 ms
        Default Isolate:
                Mean: 1472.40 ms; Deviation: 7.76 ms

The test cases has been attached in case you want to play with them.

Best regards,
Gabor Ballabas

----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.

/*
 * Benchmark - Isolate/Context performance
 * Usage: isolate-context-benchmark [number_of_tests]
 */

#include <v8.h>
#include <cstdlib>
#include <cassert>
#include "tester.h"

using namespace v8;
using namespace std;


class EngineWithOwnIsolate {
public:
    EngineWithOwnIsolate()
    {
        m_isolate = Isolate::New();
        m_isolate->Enter();
        m_context = Context::New();
        m_isolate->Exit();
    }

    ~EngineWithOwnIsolate()
    {
        m_isolate->Enter();
        m_context.Dispose();
        m_isolate->Exit();
        m_isolate->Dispose();
    }

    void doStuff()
    {
        m_isolate->Enter();
        m_context->Enter();

        m_context->Exit();
        m_isolate->Exit();
    }

    void doMoreStuff()
    {
        m_isolate->Enter();
        m_context->Enter();

        HandleScope scope;
        Handle<Value> str = String::New("666");
        Handle<Value> num = str->ToNumber();

        m_context->Exit();
        m_isolate->Exit();
    }

    void executeScript()
    {
        m_isolate->Enter();
        m_context->Enter();

        HandleScope scope;
        Handle<String> source = String::New("for (var i = 0; i < 100; ++i) {"
                                            "    var j = i + 1;"
                                            "}");
        Handle<Script> script = Script::Compile(source);
        assert(!script.IsEmpty());
        Handle<Value> result = script->Run();
        assert(!result.IsEmpty());

        m_context->Exit();
        m_isolate->Exit();
    }

private:
    EngineWithOwnIsolate(const EngineWithOwnIsolate&);
    EngineWithOwnIsolate& operator=(const EngineWithOwnIsolate&);

    Isolate* m_isolate;
    Persistent<Context> m_context;
};


class EngineWithDefaultIsolate {
public:
    EngineWithDefaultIsolate()
    {
        m_context = Context::New();
    }
    
    ~EngineWithDefaultIsolate()
    {
        m_context.Dispose();
    }

    void doStuff()
    {
        m_context->Enter();

        m_context->Exit();
    }

    void doMoreStuff()
    {
        m_context->Enter();

        HandleScope scope;
        Handle<Value> num = String::New("666");
        num->ToNumber();

        m_context->Exit();
    }

    void executeScript()
    {
        m_context->Enter();

        HandleScope scope;
        Handle<String> source = String::New("for (var i = 0; i < 100; ++i) {"
                                            "    var j = i + 1;"
                                            "}");
        Handle<Script> script = Script::Compile(source);
        assert(!script.IsEmpty());
        Handle<Value> result = script->Run();
        assert(!result.IsEmpty());

        m_context->Exit();
    }

private:
    EngineWithDefaultIsolate(const EngineWithDefaultIsolate&);
    EngineWithDefaultIsolate& operator=(const EngineWithDefaultIsolate&);

    Persistent<Context> m_context;
};


int main(int argc, char* argv[])
{
    if (argc > 2) {
        return 666;
    }

    int number_of_tests = 1;
    if (argc == 2) {
        int num = atoi(argv[1]);
        if (num) {
            number_of_tests = num;
        } else {
            return 666;
        }
    }

    HandleScope scope;
    Persistent<Context> context = Context::New();
    Context::Scope context_scope(context);
    Handle<Value> result;

    const int NUMBER_OF_LOOPS = 100000;

    EngineWithOwnIsolate* engine_with_own_isolate = new EngineWithOwnIsolate();
    EngineWithDefaultIsolate* engine_with_default_isolate = new EngineWithDefaultIsolate();

    Tester* ownIsolateTester = new Tester();
    Tester* defaultIsolateTester = new Tester();

    for (int i = 0; i < number_of_tests; ++i) {
        ownIsolateTester->startMeasuring();
        for (int i = 0; i < NUMBER_OF_LOOPS; ++i) {
            engine_with_own_isolate->doStuff();
        }
        ownIsolateTester->endMeasuring();

        defaultIsolateTester->startMeasuring();
        for (int i = 0; i < NUMBER_OF_LOOPS; ++i) {
            engine_with_default_isolate->doStuff();
        }
        defaultIsolateTester->endMeasuring();
    }

    printf("doStuff() tests:\n");
    printf("\tOwn Isolate:\n");
    printf("\t\tMean: %.2lf ms; ", ownIsolateTester->getMean());
    printf("Deviation: %.2lf ms\n", ownIsolateTester->getDeviation());

    printf("\tDefault Isolate:\n");
    printf("\t\tMean: %.2lf ms; ", defaultIsolateTester->getMean());
    printf("Deviation: %.2lf ms\n", defaultIsolateTester->getDeviation());

    ownIsolateTester->clear();
    defaultIsolateTester->clear();
    for (int i = 0; i < number_of_tests; ++i) {
        ownIsolateTester->startMeasuring();
        for (int i = 0; i < NUMBER_OF_LOOPS; ++i) {
            engine_with_own_isolate->doMoreStuff();
        }
        ownIsolateTester->endMeasuring();

        defaultIsolateTester->startMeasuring();
        for (int i = 0; i < NUMBER_OF_LOOPS; ++i) {
            engine_with_default_isolate->doMoreStuff();
        }
        defaultIsolateTester->endMeasuring();
    }

    printf("doMoreStuff() tests:\n");
    printf("\tOwn Isolate:\n");
    printf("\t\tMean: %.2lf ms; ", ownIsolateTester->getMean());
    printf("Deviation: %.2lf ms\n", ownIsolateTester->getDeviation());

    printf("\tDefault Isolate:\n");
    printf("\t\tMean: %.2lf ms; ", defaultIsolateTester->getMean());
    printf("Deviation: %.2lf ms\n", defaultIsolateTester->getDeviation());

    ownIsolateTester->clear();
    defaultIsolateTester->clear();
    for (int i = 0; i < number_of_tests; ++i) {
        ownIsolateTester->startMeasuring();
        for (int i = 0; i < NUMBER_OF_LOOPS; ++i) {
            engine_with_own_isolate->executeScript();
        }
        ownIsolateTester->endMeasuring();

        defaultIsolateTester->startMeasuring();
        for (int i = 0; i < NUMBER_OF_LOOPS; ++i) {
            engine_with_default_isolate->executeScript();
        }
        defaultIsolateTester->endMeasuring();
    }

    printf("executeScript() tests:\n");
    printf("\tOwn Isolate:\n");
    printf("\t\tMean: %.2lf ms; ", ownIsolateTester->getMean());
    printf("Deviation: %.2lf ms\n", ownIsolateTester->getDeviation());

    printf("\tDefault Isolate:\n");
    printf("\t\tMean: %.2lf ms; ", defaultIsolateTester->getMean());
    printf("Deviation: %.2lf ms\n", defaultIsolateTester->getDeviation());

    delete engine_with_own_isolate;
    delete engine_with_default_isolate;
    delete ownIsolateTester;

    context.Dispose();

    return 0;
}



#include "tester.h"
#include <cmath>


Tester::Tester()
{
    m_results = new vector<double>();
}


Tester::~Tester()
{
    delete m_results;
}


void Tester::startMeasuring()
{
    gettimeofday(&m_start, NULL);
}


void Tester::endMeasuring()
{
    gettimeofday(&m_end, NULL);
    m_results->push_back(getTimeDiff());
}


double Tester::getLastResult() const
{
    return m_results->back();
}


int Tester::getNumberOfTests() const
{
    return m_results->size();
}


double Tester::getMean() const
{
    double sum = 0;
    for (vector<double>::iterator it = m_results->begin();
            it != m_results->end(); ++it) {
        sum += *it;
    }
    return sum / m_results->size();
}


double Tester::getVariance() const
{
    double variance_numerator = 0;
    for (vector<double>::iterator it = m_results->begin();
            it != m_results->end(); ++it) {
        variance_numerator += pow(*it - getMean(), 2);
    }
    return variance_numerator / m_results->size();
}


double Tester::getDeviation() const
{
    return sqrt(getVariance());
}


Tester::tester_iterator Tester::begin()
{
    return m_results->begin();
}


Tester::tester_iterator Tester::end()
{
    return m_results->end();
}


void Tester::clear()
{
    m_results->clear();
}


double Tester::getTimeDiff()
{
    m_startTime = m_start.tv_sec * 1000000 + m_start.tv_usec;
    m_endTime = m_end.tv_sec * 1000000 + m_end.tv_usec;    
    return (m_endTime - m_startTime) / 1000;
}


#ifndef TESTER_H
#define TESTER_H


#include <vector>
#include <iterator>
#include <sys/time.h>
using namespace std;


class Tester {
public:
    Tester();
    ~Tester();
    void startMeasuring();
    void endMeasuring();
    int getNumberOfTests() const;
    double getMean() const;
    double getVariance() const;
    double getDeviation() const;
    double getLastResult() const;

    typedef vector<double>::const_iterator tester_iterator;
    tester_iterator begin();
    tester_iterator end();
    void clear();

private:
    double getTimeDiff();

    Tester(const Tester&);
    Tester& operator=(const Tester&);

    vector<double>* m_results;
    struct timeval m_start;
    struct timeval m_end;
    double m_startTime;
    double m_endTime;
};


#endif
_______________________________________________
Qt-script mailing list
[email protected]
http://lists.qt.nokia.com/mailman/listinfo/qt-script

Reply via email to