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