// V8 multi-eval benchmark - 1000 scripts in same Isolate // // Tests compile + eval performance for same vs varied scripts // // Build: cmake --build build/release --target bench-v8-multi-eval // Usage: ./bench-v8-multi-eval #include #include #include #include #include using namespace v8; class Timer { public: Timer() { start(); } void start() { start_ = std::chrono::high_resolution_clock::now(); } void reset() { start(); } double elapsedMs() const { auto now = std::chrono::high_resolution_clock::now(); return std::chrono::duration(now - start_).count(); } private: std::chrono::high_resolution_clock::time_point start_; }; static double getRSSMB() { struct rusage usage; getrusage(RUSAGE_SELF, &usage); #ifdef __APPLE__ return usage.ru_maxrss / (1024.0 * 1024.0); #else return usage.ru_maxrss / 1024.0; #endif } int main(int argc, char* argv[]) { constexpr int NUM_SCRIPTS = 1000; // Initialize V8 V8::InitializeICUDefaultLocation(argv[0]); V8::InitializeExternalStartupData(argv[0]); std::unique_ptr platform = platform::NewDefaultPlatform(); V8::InitializePlatform(platform.get()); V8::Initialize(); // Create Isolate + Context Isolate::CreateParams create_params; create_params.array_buffer_allocator = ArrayBuffer::Allocator::NewDefaultAllocator(); Isolate* isolate = Isolate::New(create_params); { Isolate::Scope isolate_scope(isolate); HandleScope handle_scope(isolate); Local context = Context::New(isolate); Context::Scope context_scope(context); // ============ SAME SCRIPT (1000x) ============ { Timer timer; const char* sameScript = "function compute(n) { var sum = 0; for (var j = 0; j < n; j++) sum += j; return sum; } compute(100)"; for (int i = 0; i < NUM_SCRIPTS; i++) { char nameBuf[32]; snprintf(nameBuf, sizeof(nameBuf), "same_%d.js", i); Local source = String::NewFromUtf8(isolate, sameScript).ToLocalChecked(); ScriptOrigin origin(String::NewFromUtf8(isolate, nameBuf).ToLocalChecked()); TryCatch try_catch(isolate); Local