Skip to content

Instantly share code, notes, and snippets.

@billywhizz
Created November 17, 2010 03:08
Show Gist options
  • Save billywhizz/702918 to your computer and use it in GitHub Desktop.
Save billywhizz/702918 to your computer and use it in GitHub Desktop.
#include <node.h>
#include <node_buffer.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
using namespace v8;
using namespace node;
static Persistent<String> on_call_sym;
class Binder : public ObjectWrap {
private:
Persistent<Function> _cb;
bool _bound;
public:
static void Initialize (v8::Handle<v8::Object> target)
{
HandleScope scope;
Local<FunctionTemplate> t = FunctionTemplate::New(New);
t->InstanceTemplate()->SetInternalFieldCount(1);
NODE_SET_PROTOTYPE_METHOD(t, "callMe", CallMe);
NODE_SET_PROTOTYPE_METHOD(t, "callMe2", CallMe2);
on_call_sym = NODE_PSYMBOL("onCall");
target->Set(String::NewSymbol("Binder"), t->GetFunction());
}
protected:
static Handle<Value> New (const Arguments& args)
{
HandleScope scope;
Binder *binder = new Binder();
binder->Wrap(args.This());
return args.This();
}
static Handle<Value> CallMe2(const Arguments &args) {
HandleScope scope;
Binder *binder = ObjectWrap::Unwrap<Binder>(args.This());
if (!args[0]->IsString()) {
return ThrowException(Exception::TypeError(String::New("Argument must be a string")));
}
Local<Value> cb_value = binder->handle_->Get(on_call_sym);
Local<Function> cb;
if (cb_value->IsFunction()) {
cb = Local<Function>::Cast(cb_value);
Local<Value> argv[1] = {args[0]->ToString()};
Local<Value> retval = cb->Call(binder->handle_, 1, argv);
}
String::AsciiValue format(args[0]->ToString());
return scope.Close(Integer::New(0));
}
static Handle<Value> CallMe(const Arguments &args) {
HandleScope scope;
Binder *binder = ObjectWrap::Unwrap<Binder>(args.This());
if (!args[0]->IsString()) {
return ThrowException(Exception::TypeError(String::New("Argument must be a string")));
}
if(!binder->_bound) {
printf("binding\n");
Local<Value> cb_value = binder->handle_->Get(on_call_sym);
if (cb_value->IsFunction()) {
binder->_cb = Persistent<Function>::New(Local<Function>::Cast(cb_value));
binder->_bound = true;
}
}
Local<Value> argv[1] = {args[0]->ToString()};
Local<Value> retval = binder->_cb->Call(binder->handle_, 1, argv);
String::AsciiValue format(args[0]->ToString());
return scope.Close(Integer::New(0));
}
Binder () : ObjectWrap ()
{
}
~Binder ()
{
}
};
extern "C" void
init (Handle<Object> target)
{
HandleScope scope;
Binder::Initialize(target);
}
var Binder = require("./lib/binder").Binder;
var binder = new Binder();
binder.onCall = function(message) {
counter++;
};
var counter = 0;
var then = new Date().getTime();
var runs = process.ARGV[2];
for(var i=0; i<runs; i++) {
binder.callMe("hello");
}
var now = new Date().getTime();
var elapsed = ((now - then)/1000).toFixed(3);
console.log("early-bound: " + counter + " in " + elapsed + " seconds. ops/sec: " + (counter / elapsed).toFixed(2));
var counter = 0;
var then = new Date().getTime();
var runs = process.ARGV[2];
for(var i=0; i<runs; i++) {
binder.callMe2("hello");
}
var now = new Date().getTime();
var elapsed = ((now - then)/1000).toFixed(3);
console.log("late-bound: " + counter + " in " + elapsed + " seconds. ops/sec: " + (counter / elapsed).toFixed(2));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment