1
0
forked from Mirror/wren
Files
wren/test/api/benchmark.c
Bob Nystrom e0ac88c22a Revamp wrenCall to work with slots.
Now, you call wrenEnsureSlots() and then wrenSetSlot___() to set up the
receiver and arguments before the call. Then wrenCall() is passed a
handle to the stub function that makes the call. After that, you can
get the result using wrenGetSlot___().

This is a little more verbose to use, but it's more flexible, simpler,
and much faster in the VM. The call benchmark is 185% of the previous
speed.
2015-12-29 07:58:47 -08:00

82 lines
2.0 KiB
C

#include <string.h>
#include <time.h>
#include "benchmark.h"
static void arguments(WrenVM* vm)
{
double result = 0;
result += wrenGetSlotDouble(vm, 1);
result += wrenGetSlotDouble(vm, 2);
result += wrenGetSlotDouble(vm, 3);
result += wrenGetSlotDouble(vm, 4);
wrenSetSlotDouble(vm, 0, result);
}
const char* testScript =
"class Test {\n"
" static method(a, b, c, d) { a + b + c + d }\n"
"}\n";
static void call(WrenVM* vm)
{
int iterations = (int)wrenGetSlotDouble(vm, 1);
// Since the VM is not re-entrant, we can't call from within this foreign
// method. Instead, make a new VM to run the call test in.
WrenConfiguration config;
wrenInitConfiguration(&config);
WrenVM* otherVM = wrenNewVM(&config);
wrenInterpret(otherVM, testScript);
WrenValue* method = wrenMakeCallHandle(otherVM, "method(_,_,_,_)");
wrenEnsureSlots(otherVM, 1);
wrenGetVariable(otherVM, "main", "Test", 0);
WrenValue* testClass = wrenGetSlotValue(otherVM, 0);
double startTime = (double)clock() / CLOCKS_PER_SEC;
double result = 0;
for (int i = 0; i < iterations; i++)
{
wrenEnsureSlots(otherVM, 5);
wrenSetSlotValue(otherVM, 0, testClass);
wrenSetSlotDouble(otherVM, 1, 1.0);
wrenSetSlotDouble(otherVM, 2, 2.0);
wrenSetSlotDouble(otherVM, 3, 3.0);
wrenSetSlotDouble(otherVM, 4, 4.0);
wrenCall(otherVM, method);
result += wrenGetSlotDouble(otherVM, 0);
}
double elapsed = (double)clock() / CLOCKS_PER_SEC - startTime;
wrenReleaseValue(otherVM, testClass);
wrenReleaseValue(otherVM, method);
wrenFreeVM(otherVM);
if (result == (1.0 + 2.0 + 3.0 + 4.0) * iterations)
{
wrenSetSlotDouble(vm, 0, elapsed);
}
else
{
// Got the wrong result.
wrenSetSlotBool(vm, 0, false);
}
}
WrenForeignMethodFn benchmarkBindMethod(const char* signature)
{
if (strcmp(signature, "static Benchmark.arguments(_,_,_,_)") == 0) return arguments;
if (strcmp(signature, "static Benchmark.call(_)") == 0) return call;
return NULL;
}