forked from Mirror/wren
Add a benchmark for wrenCall().
This commit is contained in:
@ -226,6 +226,12 @@ WrenInterpretResult wrenCallVarArgs(WrenVM* vm, WrenValue* method,
|
||||
WrenValue** returnValue,
|
||||
const char* argTypes, va_list args);
|
||||
|
||||
// Gets the numeric value of [value].
|
||||
//
|
||||
// It is an error to call this if the value is not a number.
|
||||
double wrenGetValueDouble(WrenVM* vm, WrenValue* value);
|
||||
// TODO: Functions for other types.
|
||||
|
||||
// Releases the reference stored in [value]. After calling this, [value] can no
|
||||
// longer be used.
|
||||
void wrenReleaseValue(WrenVM* vm, WrenValue* value);
|
||||
|
||||
@ -1474,9 +1474,17 @@ WrenValue* wrenCaptureValue(WrenVM* vm, Value value)
|
||||
return wrappedValue;
|
||||
}
|
||||
|
||||
double wrenGetValueDouble(WrenVM* vm, WrenValue* value)
|
||||
{
|
||||
ASSERT(value != NULL, "Value cannot be NULL.");
|
||||
ASSERT(IS_NUM(value->value), "Value must be a number.");
|
||||
|
||||
return AS_NUM(value->value);
|
||||
}
|
||||
|
||||
void wrenReleaseValue(WrenVM* vm, WrenValue* value)
|
||||
{
|
||||
ASSERT(value != NULL, "NULL value.");
|
||||
ASSERT(value != NULL, "Value cannot be NULL.");
|
||||
|
||||
// Update the VM's head pointer if we're releasing the first handle.
|
||||
if (vm->valueHandles == value) vm->valueHandles = value->next;
|
||||
@ -1734,7 +1742,7 @@ void wrenSetSlotBool(WrenVM* vm, int slot, bool value)
|
||||
|
||||
void wrenSetSlotBytes(WrenVM* vm, int slot, const char* bytes, int length)
|
||||
{
|
||||
ASSERT(bytes != NULL, "Byte arraybytes cannot be NULL.");
|
||||
ASSERT(bytes != NULL, "Byte array cannot be NULL.");
|
||||
setSlot(vm, slot, wrenNewString(vm, bytes, (size_t)length));
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "benchmark.h"
|
||||
|
||||
@ -14,9 +15,56 @@ static void arguments(WrenVM* vm)
|
||||
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 = wrenGetMethod(otherVM, "main", "Test", "method(_,_,_,_)");
|
||||
|
||||
double startTime = (double)clock() / CLOCKS_PER_SEC;
|
||||
|
||||
double result = 0;
|
||||
for (int i = 0; i < iterations; i++)
|
||||
{
|
||||
WrenValue* resultValue;
|
||||
wrenCall(otherVM, method, &resultValue, "dddd", 1.0, 2.0, 3.0, 4.0);
|
||||
result += wrenGetValueDouble(otherVM, resultValue);
|
||||
wrenReleaseValue(otherVM, resultValue);
|
||||
}
|
||||
|
||||
double elapsed = (double)clock() / CLOCKS_PER_SEC - startTime;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ static WrenForeignClassMethods bindForeignClass(
|
||||
}
|
||||
|
||||
static void afterLoad(WrenVM* vm) {
|
||||
if (strstr(testName, "call.wren") != NULL) callRunTests(vm);
|
||||
if (strstr(testName, "/call.wren") != NULL) callRunTests(vm);
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
|
||||
9
test/benchmark/api_call.wren
Normal file
9
test/benchmark/api_call.wren
Normal file
@ -0,0 +1,9 @@
|
||||
class Benchmark {
|
||||
foreign static call(iterations)
|
||||
}
|
||||
|
||||
var result = Benchmark.call(1000000)
|
||||
// Returns false if it didn't calculate the right value. Otherwise returns the
|
||||
// elapsed time.
|
||||
System.print(result is Num)
|
||||
System.print("elapsed: %(result)")
|
||||
@ -51,6 +51,8 @@ def BENCHMARK(name, pattern):
|
||||
regex = re.compile(pattern + "\n" + r"elapsed: (\d+\.\d+)", re.MULTILINE)
|
||||
BENCHMARKS.append([name, regex, None])
|
||||
|
||||
BENCHMARK("api_call", "true")
|
||||
|
||||
BENCHMARK("api_foreign_method", "100000000")
|
||||
|
||||
BENCHMARK("binary_trees", """stretch tree of depth 13 check: -1
|
||||
|
||||
Reference in New Issue
Block a user