Ich benutze V8, um einige benutzerdefinierte Javascript-Code ausführen, OnUpdate
Funktion JS Welt ausgesetzt. Gesamtcode funktioniert gut, aber zur Zeit bin ich besorgt über die Leistung von unter Code - ist es erforderlich, v8::Locker
für die Ausführung einer benutzerdefinierten Funktion greifen? Instruments.app
zeigt hier Code viel zu viel Zeit in v8::Locker
und Destruktor verbringt -Muss v8 :: Locker vor dem Aufruf von v8 :: Function :: Call abgerufen werden?
90 ms (in der Ausführung eigentlichen Code) vs ~ 4000ms (von Locker
& ~Locker
) - das absurd ist und ich glaube, ich könnte etwas falsch machen.
Also meine grundlegende Frage ist es wirklich notwendig, v8::Locker
greifen, um eine v8::Function::Call
auszuführen? Im aktuellen Zustand, wenn ich auf Kommentar v8::Locker
ich unten Fehlermeldung:
# Fatal error in HandleScope::HandleScope
# Entering the V8 API without proper locking in place
-Code-Schnipsel:
int Bucket::send_doc_update_bucket(const char *msg) {
Locker locker(GetIsolate());
Isolate::Scope isolate_scope(GetIsolate());
HandleScope handle_scope(GetIsolate());
Local<Context> context = Local<Context>::New(GetIsolate(), context_);
Context::Scope context_scope(context);
TryCatch try_catch;
Local<Value> args[1];
args[0] = String::NewFromUtf8(GetIsolate(), msg);
assert(!try_catch.HasCaught());
Handle<Value> val;
if(!context->Global()->Get(context,
createUtf8String(GetIsolate(),
"OnUpdate")).ToLocal(&val) ||
!val->IsFunction()) {
return 3;
}
Handle<Function> on_doc_update = Handle<Function>::Cast(val);
on_doc_update->Call(context, context->Global(), 1, args);
if (try_catch.HasCaught()) {
//w->last_exception = ExceptionString(GetIsolate(), &try_catch);
return 2;
}
return 0;
}
Wenn der Code irgendeine Art von Multithreading hat, erhalten häufig locking apis hohe Nutzungsbeträge, einfach weil sie den Thread blockieren, wenn ein anderer sie hält, nicht weil sie teuer sind, sondern weil sie ihre Arbeit machen. – Yakk
Yakk, I verstehe deinen Standpunkt - aber es ist nicht klar, ob das hier der Fall ist. In diesem Fall ist 'v8 :: Locker 'an jede' v8 :: Isolate'-Instanz gebunden, die mehrere parallele Code-Ausführungen mit' v8 :: Context 'erlaubt, aber ich glaube, dass ich v8 verwende - nur ein Context läuft pro Isolat. Link zum Repo - https://github.com/abhi-bit/eventing/ – Abhi
Sie müssen nur v8 :: Locker Objekte erstellen und zerstören, wenn Sie tatsächlich zwischen Threads wechseln. Wenn Sie zu jeder Zeit auf das V8-Isolat von demselben Betriebssystem-Thread zugreifen, können Sie ein Locker erstellen und es für eine lange Zeit aktiv lassen. Ich denke, GetIsolate() ist immer noch ein ziemlich teurer Anruf, und Sie möchten möglicherweise das Ergebnis in einer lokalen Variablen zwischenspeichern, wenn Sie es mehrmals aufrufen. –