JavaScript 表现不一致 (V8)
JavaScript not performing consistently (V8)
我有以下 JavaScript,它在一组分数中执行 Tournament selection。
// Benchmark Tests
benchmark( 1e2 );
benchmark( 1e3 );
benchmark( 1e4 );
benchmark( 1e6 );
benchmark( 1e4, 50, 20 );
// Selection Function
function tournamentSelection( population, size, probability ) {
var participants = [];
for( var i = 0; i < size; i++ ) {
var selected = population[ Math.random() * population.length << 0 ];
participants.push( selected );
}
participants.sort( ( a, b ) => b.Score - a.Score );
for( var i = 0; i < size; i++ )
if ( Math.random() < probability | i === size - 1 )
return participants[i];
}
// Benchmark Function
function benchmark( iterations, populationSize, tournamentSize, probability ) {
iterations = iterations || 1e3;
populationSize = populationSize || 50;
tournamentSize = tournamentSize || 5;
probability = probability || 0.75;
var population = [];
while( populationSize-- )
population.push( { Score: Math.random() * 1e6 } );
var start = performance.now();
for( var i = 0; i < iterations; i++ ) {
var selected = tournamentSelection( population, tournamentSize, probability )
}
var end = performance.now();
var total = end - start;
var avgInNS = ( total * 1e6 ) / iterations;
console.log( iterations
+ ' iterations took '
+ total.toFixed( 3 )
+ 'ms ('
+ avgInNS.toFixed( 3 )
+ 'ns avg. per iteration)' );
}
我注意到随着迭代次数的增加,平均执行时间会减少。我相信这是 V8 的运行时优化所做的,但是关于 如何 它正在被优化,没有给出任何线索。更神秘的是,当 运行 在 NodeJS 中指定标志 --allow-natives-syntax
和 %NeverOptimizeFunction(tournamentSelection);
时,不同的性能不固定。
我的目标是优化此选择算法,使其表现更一致。我假设对 sort()
的调用是其中最昂贵的操作,因为增加锦标赛 size
会对性能产生巨大影响。但是,如果这是在幕后进行优化,我实际上没有任何选择,因为 V8 使用快速排序本机实现了这一点。
有人知道 V8 在做什么吗?此外,我们将不胜感激任何改进算法性能的建议。
编辑:这是 NodeJS 环境中 运行 测试用例 #2 的分析日志:
Statistical profiling result from isolate-0x3578c70-v8.log, (73 ticks, 0 unaccounted, 0 excluded).
[Shared libraries]:
ticks total nonlib name
5 6.8% /usr/bin/node
1 1.4% /lib/x86_64-linux-gnu/libc-2.27.so
[JavaScript]:
ticks total nonlib name
1 1.4% 1.5% LazyCompile: ~participants.sort /home/haus/Desktop/Bostrom/Genetics/Selection.js:82:22
1 1.4% 1.5% LazyCompile: module.exports.Tournament /home/haus/Desktop/Bostrom/Genetics/Selection.js:67:38
[C++]:
ticks total nonlib name
23 31.5% 34.3% node::contextify::ContextifyScript::New(v8::FunctionCallbackInfo<v8::Value> const&)
16 21.9% 23.9% write
2 2.7% 3.0% v8::internal::Zone::New(unsigned long)
2 2.7% 3.0% mprotect
1 1.4% 1.5% void v8::internal::Scanner::Advance<false, true>()
1 1.4% 1.5% v8::internal::interpreter::BytecodeRegisterOptimizer::RegisterTransfer(v8::internal::interpreter::BytecodeRegisterOptimizer::RegisterInfo*, v8::internal::interpreter::BytecodeRegisterOptimizer::RegisterInfo*)
1 1.4% 1.5% v8::internal::interpreter::BytecodeRegisterOptimizer::Flush()
1 1.4% 1.5% v8::internal::interpreter::BytecodeGenerator::VisitAssignment(v8::internal::Assignment*)
1 1.4% 1.5% v8::internal::interpreter::BytecodeArrayBuilder::StackCheck(int)
1 1.4% 1.5% v8::internal::compiler::LiveRangeConnector::ConnectRanges(v8::internal::Zone*)
1 1.4% 1.5% v8::internal::compiler::CodeAssembler::ChangeInt32ToIntPtr(v8::internal::compiler::SloppyTNode<v8::internal::Word32T>)
1 1.4% 1.5% v8::internal::StackFrame::GetCallerState(v8::internal::StackFrame::State*) const
1 1.4% 1.5% v8::internal::Scanner::Scanner(v8::internal::UnicodeCache*)
1 1.4% 1.5% v8::internal::HashTable<v8::internal::StringTable, v8::internal::StringTableShape>::Rehash()
1 1.4% 1.5% v8::internal::HashTable<v8::internal::GlobalDictionary, v8::internal::GlobalDictionaryShape>::EnsureCapacity(v8::internal::Handle<v8::internal::GlobalDictionary>, int, v8::internal::PretenureFlag)
1 1.4% 1.5% v8::internal::Factory::NewFeedbackVector(v8::internal::Handle<v8::internal::SharedFunctionInfo>, v8::internal::PretenureFlag)
1 1.4% 1.5% v8::internal::Deserializer<v8::internal::DefaultDeserializerAllocator>::ReadData(v8::internal::MaybeObject**, v8::internal::MaybeObject**, int, unsigned char*)
1 1.4% 1.5% v8::internal::DeclarationScope::AllocateScopeInfos(v8::internal::ParseInfo*, v8::internal::Isolate*, v8::internal::AnalyzeMode)
1 1.4% 1.5% v8::internal::CompilationCacheTable::PutRegExp(v8::internal::Handle<v8::internal::CompilationCacheTable>, v8::internal::Handle<v8::internal::String>, v8::base::Flags<v8::internal::JSRegExp::Flag, int>, v8::internal::Handle<v8::internal::FixedArray>)
1 1.4% 1.5% v8::internal::BufferedUtf16CharacterStream::ReadBlock()
1 1.4% 1.5% v8::internal::AstRawString::AsArrayIndex(unsigned int*) const
1 1.4% 1.5% std::ostream::sentry::sentry(std::ostream&)
1 1.4% 1.5% do_futex_wait.constprop.1
1 1.4% 1.5% cfree
1 1.4% 1.5% _dl_addr
1 1.4% 1.5% _IO_file_sync
[Summary]:
ticks total nonlib name
2 2.7% 3.0% JavaScript
65 89.0% 97.0% C++
2 2.7% 3.0% GC
6 8.2% Shared libraries
[C++ entry points]:
ticks cpp total name
25 43.9% 34.2% v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*)
18 31.6% 24.7% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
5 8.8% 6.8% v8::internal::Runtime_InterpreterDeserializeLazy(int, v8::internal::Object**, v8::internal::Isolate*)
2 3.5% 2.7% v8::internal::Runtime_KeyedStoreIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*)
2 3.5% 2.7% v8::internal::Runtime_DeserializeLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 1.8% 1.4% v8::internal::Runtime_NewClosure(int, v8::internal::Object**, v8::internal::Isolate*)
1 1.8% 1.4% v8::internal::Runtime_LoadIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*)
1 1.8% 1.4% v8::internal::Runtime_DefineClass(int, v8::internal::Object**, v8::internal::Isolate*)
1 1.8% 1.4% v8::internal::Runtime_CreateRegExpLiteral(int, v8::internal::Object**, v8::internal::Isolate*)
1 1.8% 1.4% v8::internal::Builtin_ObjectDefineProperties(int, v8::internal::Object**, v8::internal::Isolate*)
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
amount of its parent calls.
Callers occupying less than 1.0% are not shown.
ticks parent name
23 31.5% node::contextify::ContextifyScript::New(v8::FunctionCallbackInfo<v8::Value> const&)
23 100.0% v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*)
23 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
23 100.0% LazyCompile: ~NativeModule.require internal/bootstrap/loaders.js:137:34
3 13.0% Script: ~<anonymous> fs.js:1:11
3 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
3 13.0% Script: ~<anonymous> assert.js:1:11
3 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
2 8.7% Script: ~<anonymous> util.js:1:11
2 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
2 8.7% Script: ~<anonymous> stream.js:1:11
2 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
2 8.7% LazyCompile: ~startup internal/bootstrap/node.js:29:19
2 100.0% Script: ~bootstrapNodeJSCore internal/bootstrap/node.js:15:30
1 4.3% Script: ~<anonymous> tty.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 4.3% Script: ~<anonymous> perf_hooks.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 4.3% Script: ~<anonymous> net.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 4.3% Script: ~<anonymous> internal/worker.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 4.3% Script: ~<anonymous> internal/process.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 4.3% Script: ~<anonymous> internal/modules/cjs/loader.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 4.3% Script: ~<anonymous> internal/async_hooks.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 4.3% LazyCompile: ~setupProcessFatal internal/bootstrap/node.js:420:29
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 4.3% LazyCompile: ~setupNextTick internal/process/next_tick.js:5:23
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 4.3% LazyCompile: ~setupGlobalVariables internal/bootstrap/node.js:293:32
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 4.3% LazyCompile: ~setupGlobalTimeouts internal/bootstrap/node.js:342:31
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
16 21.9% write
5 31.3% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 20.0% LazyCompile: ~tryExtensions internal/modules/cjs/loader.js:208:23
1 100.0% LazyCompile: ~Module._findPath internal/modules/cjs/loader.js:220:28
1 100.0% LazyCompile: ~Module._resolveFilename internal/modules/cjs/loader.js:547:35
1 100.0% LazyCompile: ~Module._load internal/modules/cjs/loader.js:502:24
1 20.0% LazyCompile: ~setupGlobalConsole internal/bootstrap/node.js:352:30
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 100.0% Script: ~bootstrapNodeJSCore internal/bootstrap/node.js:15:30
1 20.0% LazyCompile: ~readFileSync fs.js:345:22
1 100.0% LazyCompile: ~Module._extensions..js internal/modules/cjs/loader.js:698:37
1 100.0% LazyCompile: ~Module.load internal/modules/cjs/loader.js:590:33
1 100.0% LazyCompile: ~tryModuleLoad internal/modules/cjs/loader.js:535:23
1 20.0% LazyCompile: ~getStdout internal/process/stdio.js:21:21
1 100.0% Script: ~<anonymous> console.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 100.0% LazyCompile: ~NativeModule.require internal/bootstrap/loaders.js:137:34
1 20.0% LazyCompile: ~Socket net.js:221:16
1 100.0% LazyCompile: ~WriteStream tty.js:70:21
1 100.0% LazyCompile: ~createWritableStdioStream internal/process/stdio.js:163:35
1 100.0% LazyCompile: ~getStdout internal/process/stdio.js:21:21
3 18.8% v8::internal::Runtime_InterpreterDeserializeLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 33.3% Script: ~<anonymous> :5:10
1 100.0% Script: ~<anonymous> :1:1
1 33.3% LazyCompile: ~binding internal/bootstrap/loaders.js:77:39
1 100.0% Script: ~bootstrapInternalLoaders internal/bootstrap/loaders.js:42:35
1 33.3% LazyCompile: ~_extend util.js:1231:17
1 100.0% LazyCompile: ~Socket net.js:221:16
1 100.0% LazyCompile: ~WriteStream tty.js:70:21
1 100.0% LazyCompile: ~createWritableStdioStream internal/process/stdio.js:163:35
1 6.3% v8::internal::Runtime_DeserializeLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% Script: ~<anonymous> internal/util/types.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 100.0% LazyCompile: ~NativeModule.require internal/bootstrap/loaders.js:137:34
1 100.0% Script: ~<anonymous> internal/encoding.js:1:11
5 6.8% /usr/bin/node
2 40.0% v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*)
2 100.0% LazyCompile: ~binding internal/bootstrap/loaders.js:77:39
1 50.0% Script: ~<anonymous> internal/util.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 100.0% LazyCompile: ~NativeModule.require internal/bootstrap/loaders.js:137:34
1 50.0% LazyCompile: ~setupProcessICUVersions internal/bootstrap/node.js:474:35
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 100.0% Script: ~bootstrapNodeJSCore internal/bootstrap/node.js:15:30
1 20.0% v8::internal::Runtime_DefineClass(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% Script: ~<anonymous> internal/worker.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 100.0% LazyCompile: ~NativeModule.require internal/bootstrap/loaders.js:137:34
1 100.0% Script: ~<anonymous> internal/process.js:1:11
1 20.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~emitBeforeScript internal/async_hooks.js:340:26
1 100.0% LazyCompile: ~_tickCallback internal/process/next_tick.js:41:25
1 100.0% LazyCompile: ~Module.runMain internal/modules/cjs/loader.js:729:26
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
2 2.7% v8::internal::Zone::New(unsigned long)
2 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 50.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 100.0% Script: ~bootstrapNodeJSCore internal/bootstrap/node.js:15:30
1 50.0% LazyCompile: ~emitAfterScript internal/async_hooks.js:354:25
1 100.0% LazyCompile: ~_tickCallback internal/process/next_tick.js:41:25
1 100.0% LazyCompile: ~Module.runMain internal/modules/cjs/loader.js:729:26
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
2 2.7% mprotect
2 100.0% v8::internal::Runtime_InterpreterDeserializeLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 50.0% LazyCompile: ~NativeModule.require internal/bootstrap/loaders.js:137:34
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 100.0% Script: ~bootstrapNodeJSCore internal/bootstrap/node.js:15:30
1 50.0% LazyCompile: module.exports.Tournament /home/haus/Desktop/Bostrom/Genetics/Selection.js:67:38
1 100.0% Script: ~<anonymous> /home/haus/Desktop/Bostrom/test.js:1:11
1 100.0% LazyCompile: ~Module._compile internal/modules/cjs/loader.js:650:37
1 100.0% LazyCompile: ~Module._extensions..js internal/modules/cjs/loader.js:698:37
1 1.4% void v8::internal::Scanner::Advance<false, true>()
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~formatValue util.js:420:21
1 100.0% LazyCompile: ~inspect util.js:291:17
1 100.0% LazyCompile: ~formatWithOptions util.js:173:27
1 100.0% LazyCompile: ~Console.(anonymous function) console.js:186:47
1 1.4% v8::internal::interpreter::BytecodeRegisterOptimizer::RegisterTransfer(v8::internal::interpreter::BytecodeRegisterOptimizer::RegisterInfo*, v8::internal::interpreter::BytecodeRegisterOptimizer::RegisterInfo*)
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~InnerArraySort native array.js:487:24
1 100.0% LazyCompile: ~sort native array.js:708:46
1 100.0% Script: ~<anonymous> internal/modules/cjs/helpers.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 1.4% v8::internal::interpreter::BytecodeRegisterOptimizer::Flush()
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~Module._load internal/modules/cjs/loader.js:502:24
1 100.0% LazyCompile: ~Module.runMain internal/modules/cjs/loader.js:729:26
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 100.0% Script: ~bootstrapNodeJSCore internal/bootstrap/node.js:15:30
1 1.4% v8::internal::interpreter::BytecodeGenerator::VisitAssignment(v8::internal::Assignment*)
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% Script: ~<anonymous> internal/url.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 100.0% LazyCompile: ~NativeModule.require internal/bootstrap/loaders.js:137:34
1 100.0% Script: ~<anonymous> fs.js:1:11
1 1.4% v8::internal::interpreter::BytecodeArrayBuilder::StackCheck(int)
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~readFileSync fs.js:345:22
1 100.0% LazyCompile: ~Module._extensions..js internal/modules/cjs/loader.js:698:37
1 100.0% LazyCompile: ~Module.load internal/modules/cjs/loader.js:590:33
1 100.0% LazyCompile: ~tryModuleLoad internal/modules/cjs/loader.js:535:23
1 1.4% v8::internal::compiler::LiveRangeConnector::ConnectRanges(v8::internal::Zone*)
1 100.0% v8::internal::Runtime_KeyedStoreIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~newAsyncId internal/async_hooks.js:254:20
1 100.0% LazyCompile: ~TickObject internal/process/next_tick.js:74:16
1 100.0% LazyCompile: ~nextTick internal/process/next_tick.js:96:20
1 100.0% LazyCompile: ~onwrite _stream_writable.js:445:17
1 1.4% v8::internal::compiler::CodeAssembler::ChangeInt32ToIntPtr(v8::internal::compiler::SloppyTNode<v8::internal::Word32T>)
1 100.0% v8::internal::Runtime_KeyedStoreIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~createUnsafeArrayBuffer buffer.js:115:33
1 100.0% LazyCompile: ~createPool buffer.js:124:20
1 100.0% Script: ~<anonymous> buffer.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 1.4% v8::internal::StackFrame::GetCallerState(v8::internal::StackFrame::State*) const
1 100.0% v8::internal::Runtime_LoadIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% Script: ~<anonymous> v8.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 100.0% LazyCompile: ~NativeModule.require internal/bootstrap/loaders.js:137:34
1 100.0% Script: ~<anonymous> internal/error-serdes.js:1:11
1 1.4% v8::internal::Scanner::Scanner(v8::internal::UnicodeCache*)
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~realpathSync fs.js:1349:22
1 100.0% LazyCompile: ~toRealPath internal/modules/cjs/loader.js:201:20
1 100.0% LazyCompile: ~tryFile internal/modules/cjs/loader.js:193:17
1 100.0% LazyCompile: ~tryExtensions internal/modules/cjs/loader.js:208:23
1 1.4% v8::internal::HashTable<v8::internal::StringTable, v8::internal::StringTableShape>::Rehash()
1 1.4% v8::internal::HashTable<v8::internal::GlobalDictionary, v8::internal::GlobalDictionaryShape>::EnsureCapacity(v8::internal::Handle<v8::internal::GlobalDictionary>, int, v8::internal::PretenureFlag)
1 100.0% v8::internal::Builtin_ObjectDefineProperties(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~setupGlobalVariables internal/bootstrap/node.js:293:32
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 100.0% Script: ~bootstrapNodeJSCore internal/bootstrap/node.js:15:30
1 1.4% v8::internal::Factory::NewFeedbackVector(v8::internal::Handle<v8::internal::SharedFunctionInfo>, v8::internal::PretenureFlag)
1 100.0% v8::internal::Runtime_NewClosure(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% Script: ~<anonymous> internal/buffer.js:1:1
1 100.0% node::contextify::ContextifyScript::RunInThisContext(v8::FunctionCallbackInfo<v8::Value> const&)
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 100.0% LazyCompile: ~NativeModule.require internal/bootstrap/loaders.js:137:34
1 1.4% v8::internal::Deserializer<v8::internal::DefaultDeserializerAllocator>::ReadData(v8::internal::MaybeObject**, v8::internal::MaybeObject**, int, unsigned char*)
1 1.4% v8::internal::DeclarationScope::AllocateScopeInfos(v8::internal::ParseInfo*, v8::internal::Isolate*, v8::internal::AnalyzeMode)
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~NativeModule.nonInternalExists internal/bootstrap/loaders.js:200:46
1 100.0% Builtin: ArrayFilter
1 100.0% Script: ~<anonymous> internal/modules/cjs/loader.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 1.4% v8::internal::CompilationCacheTable::PutRegExp(v8::internal::Handle<v8::internal::CompilationCacheTable>, v8::internal::Handle<v8::internal::String>, v8::base::Flags<v8::internal::JSRegExp::Flag, int>, v8::internal::Handle<v8::internal::FixedArray>)
1 100.0% v8::internal::Runtime_CreateRegExpLiteral(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~getColorDepth internal/tty.js:70:23
1 100.0% LazyCompile: ~Console.(anonymous function) console.js:175:49
1 100.0% LazyCompile: ~Console.(anonymous function) console.js:186:47
1 100.0% LazyCompile: ~log console.js:196:37
1 1.4% v8::internal::BufferedUtf16CharacterStream::ReadBlock()
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~Module._resolveLookupPaths internal/modules/cjs/loader.js:400:38
1 100.0% LazyCompile: ~Module._resolveFilename internal/modules/cjs/loader.js:547:35
1 100.0% LazyCompile: ~Module._load internal/modules/cjs/loader.js:502:24
1 100.0% LazyCompile: ~Module.require internal/modules/cjs/loader.js:629:36
1 1.4% v8::internal::AstRawString::AsArrayIndex(unsigned int*) const
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~Socket._writeGeneric net.js:734:42
1 100.0% LazyCompile: ~Socket._write net.js:771:35
1 100.0% LazyCompile: ~doWrite _stream_writable.js:400:17
1 100.0% LazyCompile: ~writeOrBuffer _stream_writable.js:360:23
1 1.4% std::ostream::sentry::sentry(std::ostream&)
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 100.0% Script: ~bootstrapNodeJSCore internal/bootstrap/node.js:15:30
1 1.4% do_futex_wait.constprop.1
1 1.4% cfree
1 1.4% _dl_addr
1 1.4% _IO_file_sync
1 100.0% v8::internal::Runtime_DeserializeLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~normalizeString path.js:57:25
1 100.0% LazyCompile: ~resolve path.js:1075:28
1 100.0% LazyCompile: ~Module._initPaths internal/modules/cjs/loader.js:748:29
1 100.0% Script: ~<anonymous> internal/modules/cjs/loader.js:1:11
1 1.4% LazyCompile: ~participants.sort /home/haus/Desktop/Bostrom/Genetics/Selection.js:82:22
1 100.0% LazyCompile: ~InsertionSort native array.js:500:23
1 100.0% LazyCompile: ~QuickSort native array.js:531:19
1 100.0% LazyCompile: ~InnerArraySort native array.js:487:24
1 100.0% LazyCompile: ~sort native array.js:708:46
1 100.0% LazyCompile: module.exports.Tournament /home/haus/Desktop/Bostrom/Genetics/Selection.js:67:38
1 1.4% LazyCompile: module.exports.Tournament /home/haus/Desktop/Bostrom/Genetics/Selection.js:67:38
1 100.0% Script: ~<anonymous> /home/haus/Desktop/Bostrom/test.js:1:11
1 100.0% LazyCompile: ~Module._compile internal/modules/cjs/loader.js:650:37
1 100.0% LazyCompile: ~Module._extensions..js internal/modules/cjs/loader.js:698:37
1 100.0% LazyCompile: ~Module.load internal/modules/cjs/loader.js:590:33
1 100.0% LazyCompile: ~tryModuleLoad internal/modules/cjs/loader.js:535:23
1 1.4% /lib/x86_64-linux-gnu/libc-2.27.so
您可能会考虑的另一种算法:
在基准函数中对总体进行排序
保留锦标赛分组排序的伪代码:
//in tournamentSelection fucntion
var size_of_bucket= Math.floor(populationSize/tournamentSize)
for i=1;i<=size;i++
selected=population[Math.random() *((size_of_bucket*i)-(size_of_bucket*(i-1))]
这样你只需要排序一次
基本上这个算法是将人口分成桶(桶数 = 所需的锦标赛规模)。这样可以避免多次排序。
权衡:对于低迭代,这可能会导致花费的时间增加
Update :基于 jmrk 评论:将 parseInt 更改为 Math.floor 因为它更快
这里是 V8 开发人员。
您看到的主要是函数一个接一个优化的效果(与迭代计数本身影响每次迭代的时间相反)。您对此无能为力。这就是现代 JavaScript 引擎的工作原理。它真的会引起问题吗?
显示预热后性能相当一致的一种方法是颠倒预热案例的顺序。 (提示关于误导性微基准的通常提醒 ;-))
您编辑的分析结果很奇怪;我看到了一些不同的东西。也许你得到了错误的隔离?正如您假设的那样,排序是最昂贵的部分,大约花费了 60% 的时间。正如您正确观察到的那样,tournamentSize
越小,每次迭代越快。
Array.prototype.sort
是一个(高度优化的)内部内置,所以它的性能确实是你无法控制的。传入自定义比较器函数会产生显着的性能成本,但在这种情况下,我看不到解决方法。
我有以下 JavaScript,它在一组分数中执行 Tournament selection。
// Benchmark Tests
benchmark( 1e2 );
benchmark( 1e3 );
benchmark( 1e4 );
benchmark( 1e6 );
benchmark( 1e4, 50, 20 );
// Selection Function
function tournamentSelection( population, size, probability ) {
var participants = [];
for( var i = 0; i < size; i++ ) {
var selected = population[ Math.random() * population.length << 0 ];
participants.push( selected );
}
participants.sort( ( a, b ) => b.Score - a.Score );
for( var i = 0; i < size; i++ )
if ( Math.random() < probability | i === size - 1 )
return participants[i];
}
// Benchmark Function
function benchmark( iterations, populationSize, tournamentSize, probability ) {
iterations = iterations || 1e3;
populationSize = populationSize || 50;
tournamentSize = tournamentSize || 5;
probability = probability || 0.75;
var population = [];
while( populationSize-- )
population.push( { Score: Math.random() * 1e6 } );
var start = performance.now();
for( var i = 0; i < iterations; i++ ) {
var selected = tournamentSelection( population, tournamentSize, probability )
}
var end = performance.now();
var total = end - start;
var avgInNS = ( total * 1e6 ) / iterations;
console.log( iterations
+ ' iterations took '
+ total.toFixed( 3 )
+ 'ms ('
+ avgInNS.toFixed( 3 )
+ 'ns avg. per iteration)' );
}
我注意到随着迭代次数的增加,平均执行时间会减少。我相信这是 V8 的运行时优化所做的,但是关于 如何 它正在被优化,没有给出任何线索。更神秘的是,当 运行 在 NodeJS 中指定标志 --allow-natives-syntax
和 %NeverOptimizeFunction(tournamentSelection);
时,不同的性能不固定。
我的目标是优化此选择算法,使其表现更一致。我假设对 sort()
的调用是其中最昂贵的操作,因为增加锦标赛 size
会对性能产生巨大影响。但是,如果这是在幕后进行优化,我实际上没有任何选择,因为 V8 使用快速排序本机实现了这一点。
有人知道 V8 在做什么吗?此外,我们将不胜感激任何改进算法性能的建议。
编辑:这是 NodeJS 环境中 运行 测试用例 #2 的分析日志:
Statistical profiling result from isolate-0x3578c70-v8.log, (73 ticks, 0 unaccounted, 0 excluded).
[Shared libraries]:
ticks total nonlib name
5 6.8% /usr/bin/node
1 1.4% /lib/x86_64-linux-gnu/libc-2.27.so
[JavaScript]:
ticks total nonlib name
1 1.4% 1.5% LazyCompile: ~participants.sort /home/haus/Desktop/Bostrom/Genetics/Selection.js:82:22
1 1.4% 1.5% LazyCompile: module.exports.Tournament /home/haus/Desktop/Bostrom/Genetics/Selection.js:67:38
[C++]:
ticks total nonlib name
23 31.5% 34.3% node::contextify::ContextifyScript::New(v8::FunctionCallbackInfo<v8::Value> const&)
16 21.9% 23.9% write
2 2.7% 3.0% v8::internal::Zone::New(unsigned long)
2 2.7% 3.0% mprotect
1 1.4% 1.5% void v8::internal::Scanner::Advance<false, true>()
1 1.4% 1.5% v8::internal::interpreter::BytecodeRegisterOptimizer::RegisterTransfer(v8::internal::interpreter::BytecodeRegisterOptimizer::RegisterInfo*, v8::internal::interpreter::BytecodeRegisterOptimizer::RegisterInfo*)
1 1.4% 1.5% v8::internal::interpreter::BytecodeRegisterOptimizer::Flush()
1 1.4% 1.5% v8::internal::interpreter::BytecodeGenerator::VisitAssignment(v8::internal::Assignment*)
1 1.4% 1.5% v8::internal::interpreter::BytecodeArrayBuilder::StackCheck(int)
1 1.4% 1.5% v8::internal::compiler::LiveRangeConnector::ConnectRanges(v8::internal::Zone*)
1 1.4% 1.5% v8::internal::compiler::CodeAssembler::ChangeInt32ToIntPtr(v8::internal::compiler::SloppyTNode<v8::internal::Word32T>)
1 1.4% 1.5% v8::internal::StackFrame::GetCallerState(v8::internal::StackFrame::State*) const
1 1.4% 1.5% v8::internal::Scanner::Scanner(v8::internal::UnicodeCache*)
1 1.4% 1.5% v8::internal::HashTable<v8::internal::StringTable, v8::internal::StringTableShape>::Rehash()
1 1.4% 1.5% v8::internal::HashTable<v8::internal::GlobalDictionary, v8::internal::GlobalDictionaryShape>::EnsureCapacity(v8::internal::Handle<v8::internal::GlobalDictionary>, int, v8::internal::PretenureFlag)
1 1.4% 1.5% v8::internal::Factory::NewFeedbackVector(v8::internal::Handle<v8::internal::SharedFunctionInfo>, v8::internal::PretenureFlag)
1 1.4% 1.5% v8::internal::Deserializer<v8::internal::DefaultDeserializerAllocator>::ReadData(v8::internal::MaybeObject**, v8::internal::MaybeObject**, int, unsigned char*)
1 1.4% 1.5% v8::internal::DeclarationScope::AllocateScopeInfos(v8::internal::ParseInfo*, v8::internal::Isolate*, v8::internal::AnalyzeMode)
1 1.4% 1.5% v8::internal::CompilationCacheTable::PutRegExp(v8::internal::Handle<v8::internal::CompilationCacheTable>, v8::internal::Handle<v8::internal::String>, v8::base::Flags<v8::internal::JSRegExp::Flag, int>, v8::internal::Handle<v8::internal::FixedArray>)
1 1.4% 1.5% v8::internal::BufferedUtf16CharacterStream::ReadBlock()
1 1.4% 1.5% v8::internal::AstRawString::AsArrayIndex(unsigned int*) const
1 1.4% 1.5% std::ostream::sentry::sentry(std::ostream&)
1 1.4% 1.5% do_futex_wait.constprop.1
1 1.4% 1.5% cfree
1 1.4% 1.5% _dl_addr
1 1.4% 1.5% _IO_file_sync
[Summary]:
ticks total nonlib name
2 2.7% 3.0% JavaScript
65 89.0% 97.0% C++
2 2.7% 3.0% GC
6 8.2% Shared libraries
[C++ entry points]:
ticks cpp total name
25 43.9% 34.2% v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*)
18 31.6% 24.7% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
5 8.8% 6.8% v8::internal::Runtime_InterpreterDeserializeLazy(int, v8::internal::Object**, v8::internal::Isolate*)
2 3.5% 2.7% v8::internal::Runtime_KeyedStoreIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*)
2 3.5% 2.7% v8::internal::Runtime_DeserializeLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 1.8% 1.4% v8::internal::Runtime_NewClosure(int, v8::internal::Object**, v8::internal::Isolate*)
1 1.8% 1.4% v8::internal::Runtime_LoadIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*)
1 1.8% 1.4% v8::internal::Runtime_DefineClass(int, v8::internal::Object**, v8::internal::Isolate*)
1 1.8% 1.4% v8::internal::Runtime_CreateRegExpLiteral(int, v8::internal::Object**, v8::internal::Isolate*)
1 1.8% 1.4% v8::internal::Builtin_ObjectDefineProperties(int, v8::internal::Object**, v8::internal::Isolate*)
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
amount of its parent calls.
Callers occupying less than 1.0% are not shown.
ticks parent name
23 31.5% node::contextify::ContextifyScript::New(v8::FunctionCallbackInfo<v8::Value> const&)
23 100.0% v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*)
23 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
23 100.0% LazyCompile: ~NativeModule.require internal/bootstrap/loaders.js:137:34
3 13.0% Script: ~<anonymous> fs.js:1:11
3 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
3 13.0% Script: ~<anonymous> assert.js:1:11
3 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
2 8.7% Script: ~<anonymous> util.js:1:11
2 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
2 8.7% Script: ~<anonymous> stream.js:1:11
2 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
2 8.7% LazyCompile: ~startup internal/bootstrap/node.js:29:19
2 100.0% Script: ~bootstrapNodeJSCore internal/bootstrap/node.js:15:30
1 4.3% Script: ~<anonymous> tty.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 4.3% Script: ~<anonymous> perf_hooks.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 4.3% Script: ~<anonymous> net.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 4.3% Script: ~<anonymous> internal/worker.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 4.3% Script: ~<anonymous> internal/process.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 4.3% Script: ~<anonymous> internal/modules/cjs/loader.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 4.3% Script: ~<anonymous> internal/async_hooks.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 4.3% LazyCompile: ~setupProcessFatal internal/bootstrap/node.js:420:29
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 4.3% LazyCompile: ~setupNextTick internal/process/next_tick.js:5:23
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 4.3% LazyCompile: ~setupGlobalVariables internal/bootstrap/node.js:293:32
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 4.3% LazyCompile: ~setupGlobalTimeouts internal/bootstrap/node.js:342:31
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
16 21.9% write
5 31.3% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 20.0% LazyCompile: ~tryExtensions internal/modules/cjs/loader.js:208:23
1 100.0% LazyCompile: ~Module._findPath internal/modules/cjs/loader.js:220:28
1 100.0% LazyCompile: ~Module._resolveFilename internal/modules/cjs/loader.js:547:35
1 100.0% LazyCompile: ~Module._load internal/modules/cjs/loader.js:502:24
1 20.0% LazyCompile: ~setupGlobalConsole internal/bootstrap/node.js:352:30
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 100.0% Script: ~bootstrapNodeJSCore internal/bootstrap/node.js:15:30
1 20.0% LazyCompile: ~readFileSync fs.js:345:22
1 100.0% LazyCompile: ~Module._extensions..js internal/modules/cjs/loader.js:698:37
1 100.0% LazyCompile: ~Module.load internal/modules/cjs/loader.js:590:33
1 100.0% LazyCompile: ~tryModuleLoad internal/modules/cjs/loader.js:535:23
1 20.0% LazyCompile: ~getStdout internal/process/stdio.js:21:21
1 100.0% Script: ~<anonymous> console.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 100.0% LazyCompile: ~NativeModule.require internal/bootstrap/loaders.js:137:34
1 20.0% LazyCompile: ~Socket net.js:221:16
1 100.0% LazyCompile: ~WriteStream tty.js:70:21
1 100.0% LazyCompile: ~createWritableStdioStream internal/process/stdio.js:163:35
1 100.0% LazyCompile: ~getStdout internal/process/stdio.js:21:21
3 18.8% v8::internal::Runtime_InterpreterDeserializeLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 33.3% Script: ~<anonymous> :5:10
1 100.0% Script: ~<anonymous> :1:1
1 33.3% LazyCompile: ~binding internal/bootstrap/loaders.js:77:39
1 100.0% Script: ~bootstrapInternalLoaders internal/bootstrap/loaders.js:42:35
1 33.3% LazyCompile: ~_extend util.js:1231:17
1 100.0% LazyCompile: ~Socket net.js:221:16
1 100.0% LazyCompile: ~WriteStream tty.js:70:21
1 100.0% LazyCompile: ~createWritableStdioStream internal/process/stdio.js:163:35
1 6.3% v8::internal::Runtime_DeserializeLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% Script: ~<anonymous> internal/util/types.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 100.0% LazyCompile: ~NativeModule.require internal/bootstrap/loaders.js:137:34
1 100.0% Script: ~<anonymous> internal/encoding.js:1:11
5 6.8% /usr/bin/node
2 40.0% v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*)
2 100.0% LazyCompile: ~binding internal/bootstrap/loaders.js:77:39
1 50.0% Script: ~<anonymous> internal/util.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 100.0% LazyCompile: ~NativeModule.require internal/bootstrap/loaders.js:137:34
1 50.0% LazyCompile: ~setupProcessICUVersions internal/bootstrap/node.js:474:35
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 100.0% Script: ~bootstrapNodeJSCore internal/bootstrap/node.js:15:30
1 20.0% v8::internal::Runtime_DefineClass(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% Script: ~<anonymous> internal/worker.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 100.0% LazyCompile: ~NativeModule.require internal/bootstrap/loaders.js:137:34
1 100.0% Script: ~<anonymous> internal/process.js:1:11
1 20.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~emitBeforeScript internal/async_hooks.js:340:26
1 100.0% LazyCompile: ~_tickCallback internal/process/next_tick.js:41:25
1 100.0% LazyCompile: ~Module.runMain internal/modules/cjs/loader.js:729:26
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
2 2.7% v8::internal::Zone::New(unsigned long)
2 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 50.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 100.0% Script: ~bootstrapNodeJSCore internal/bootstrap/node.js:15:30
1 50.0% LazyCompile: ~emitAfterScript internal/async_hooks.js:354:25
1 100.0% LazyCompile: ~_tickCallback internal/process/next_tick.js:41:25
1 100.0% LazyCompile: ~Module.runMain internal/modules/cjs/loader.js:729:26
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
2 2.7% mprotect
2 100.0% v8::internal::Runtime_InterpreterDeserializeLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 50.0% LazyCompile: ~NativeModule.require internal/bootstrap/loaders.js:137:34
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 100.0% Script: ~bootstrapNodeJSCore internal/bootstrap/node.js:15:30
1 50.0% LazyCompile: module.exports.Tournament /home/haus/Desktop/Bostrom/Genetics/Selection.js:67:38
1 100.0% Script: ~<anonymous> /home/haus/Desktop/Bostrom/test.js:1:11
1 100.0% LazyCompile: ~Module._compile internal/modules/cjs/loader.js:650:37
1 100.0% LazyCompile: ~Module._extensions..js internal/modules/cjs/loader.js:698:37
1 1.4% void v8::internal::Scanner::Advance<false, true>()
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~formatValue util.js:420:21
1 100.0% LazyCompile: ~inspect util.js:291:17
1 100.0% LazyCompile: ~formatWithOptions util.js:173:27
1 100.0% LazyCompile: ~Console.(anonymous function) console.js:186:47
1 1.4% v8::internal::interpreter::BytecodeRegisterOptimizer::RegisterTransfer(v8::internal::interpreter::BytecodeRegisterOptimizer::RegisterInfo*, v8::internal::interpreter::BytecodeRegisterOptimizer::RegisterInfo*)
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~InnerArraySort native array.js:487:24
1 100.0% LazyCompile: ~sort native array.js:708:46
1 100.0% Script: ~<anonymous> internal/modules/cjs/helpers.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 1.4% v8::internal::interpreter::BytecodeRegisterOptimizer::Flush()
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~Module._load internal/modules/cjs/loader.js:502:24
1 100.0% LazyCompile: ~Module.runMain internal/modules/cjs/loader.js:729:26
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 100.0% Script: ~bootstrapNodeJSCore internal/bootstrap/node.js:15:30
1 1.4% v8::internal::interpreter::BytecodeGenerator::VisitAssignment(v8::internal::Assignment*)
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% Script: ~<anonymous> internal/url.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 100.0% LazyCompile: ~NativeModule.require internal/bootstrap/loaders.js:137:34
1 100.0% Script: ~<anonymous> fs.js:1:11
1 1.4% v8::internal::interpreter::BytecodeArrayBuilder::StackCheck(int)
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~readFileSync fs.js:345:22
1 100.0% LazyCompile: ~Module._extensions..js internal/modules/cjs/loader.js:698:37
1 100.0% LazyCompile: ~Module.load internal/modules/cjs/loader.js:590:33
1 100.0% LazyCompile: ~tryModuleLoad internal/modules/cjs/loader.js:535:23
1 1.4% v8::internal::compiler::LiveRangeConnector::ConnectRanges(v8::internal::Zone*)
1 100.0% v8::internal::Runtime_KeyedStoreIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~newAsyncId internal/async_hooks.js:254:20
1 100.0% LazyCompile: ~TickObject internal/process/next_tick.js:74:16
1 100.0% LazyCompile: ~nextTick internal/process/next_tick.js:96:20
1 100.0% LazyCompile: ~onwrite _stream_writable.js:445:17
1 1.4% v8::internal::compiler::CodeAssembler::ChangeInt32ToIntPtr(v8::internal::compiler::SloppyTNode<v8::internal::Word32T>)
1 100.0% v8::internal::Runtime_KeyedStoreIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~createUnsafeArrayBuffer buffer.js:115:33
1 100.0% LazyCompile: ~createPool buffer.js:124:20
1 100.0% Script: ~<anonymous> buffer.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 1.4% v8::internal::StackFrame::GetCallerState(v8::internal::StackFrame::State*) const
1 100.0% v8::internal::Runtime_LoadIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% Script: ~<anonymous> v8.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 100.0% LazyCompile: ~NativeModule.require internal/bootstrap/loaders.js:137:34
1 100.0% Script: ~<anonymous> internal/error-serdes.js:1:11
1 1.4% v8::internal::Scanner::Scanner(v8::internal::UnicodeCache*)
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~realpathSync fs.js:1349:22
1 100.0% LazyCompile: ~toRealPath internal/modules/cjs/loader.js:201:20
1 100.0% LazyCompile: ~tryFile internal/modules/cjs/loader.js:193:17
1 100.0% LazyCompile: ~tryExtensions internal/modules/cjs/loader.js:208:23
1 1.4% v8::internal::HashTable<v8::internal::StringTable, v8::internal::StringTableShape>::Rehash()
1 1.4% v8::internal::HashTable<v8::internal::GlobalDictionary, v8::internal::GlobalDictionaryShape>::EnsureCapacity(v8::internal::Handle<v8::internal::GlobalDictionary>, int, v8::internal::PretenureFlag)
1 100.0% v8::internal::Builtin_ObjectDefineProperties(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~setupGlobalVariables internal/bootstrap/node.js:293:32
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 100.0% Script: ~bootstrapNodeJSCore internal/bootstrap/node.js:15:30
1 1.4% v8::internal::Factory::NewFeedbackVector(v8::internal::Handle<v8::internal::SharedFunctionInfo>, v8::internal::PretenureFlag)
1 100.0% v8::internal::Runtime_NewClosure(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% Script: ~<anonymous> internal/buffer.js:1:1
1 100.0% node::contextify::ContextifyScript::RunInThisContext(v8::FunctionCallbackInfo<v8::Value> const&)
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 100.0% LazyCompile: ~NativeModule.require internal/bootstrap/loaders.js:137:34
1 1.4% v8::internal::Deserializer<v8::internal::DefaultDeserializerAllocator>::ReadData(v8::internal::MaybeObject**, v8::internal::MaybeObject**, int, unsigned char*)
1 1.4% v8::internal::DeclarationScope::AllocateScopeInfos(v8::internal::ParseInfo*, v8::internal::Isolate*, v8::internal::AnalyzeMode)
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~NativeModule.nonInternalExists internal/bootstrap/loaders.js:200:46
1 100.0% Builtin: ArrayFilter
1 100.0% Script: ~<anonymous> internal/modules/cjs/loader.js:1:11
1 100.0% LazyCompile: ~NativeModule.compile internal/bootstrap/loaders.js:230:44
1 1.4% v8::internal::CompilationCacheTable::PutRegExp(v8::internal::Handle<v8::internal::CompilationCacheTable>, v8::internal::Handle<v8::internal::String>, v8::base::Flags<v8::internal::JSRegExp::Flag, int>, v8::internal::Handle<v8::internal::FixedArray>)
1 100.0% v8::internal::Runtime_CreateRegExpLiteral(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~getColorDepth internal/tty.js:70:23
1 100.0% LazyCompile: ~Console.(anonymous function) console.js:175:49
1 100.0% LazyCompile: ~Console.(anonymous function) console.js:186:47
1 100.0% LazyCompile: ~log console.js:196:37
1 1.4% v8::internal::BufferedUtf16CharacterStream::ReadBlock()
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~Module._resolveLookupPaths internal/modules/cjs/loader.js:400:38
1 100.0% LazyCompile: ~Module._resolveFilename internal/modules/cjs/loader.js:547:35
1 100.0% LazyCompile: ~Module._load internal/modules/cjs/loader.js:502:24
1 100.0% LazyCompile: ~Module.require internal/modules/cjs/loader.js:629:36
1 1.4% v8::internal::AstRawString::AsArrayIndex(unsigned int*) const
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~Socket._writeGeneric net.js:734:42
1 100.0% LazyCompile: ~Socket._write net.js:771:35
1 100.0% LazyCompile: ~doWrite _stream_writable.js:400:17
1 100.0% LazyCompile: ~writeOrBuffer _stream_writable.js:360:23
1 1.4% std::ostream::sentry::sentry(std::ostream&)
1 100.0% v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~startup internal/bootstrap/node.js:29:19
1 100.0% Script: ~bootstrapNodeJSCore internal/bootstrap/node.js:15:30
1 1.4% do_futex_wait.constprop.1
1 1.4% cfree
1 1.4% _dl_addr
1 1.4% _IO_file_sync
1 100.0% v8::internal::Runtime_DeserializeLazy(int, v8::internal::Object**, v8::internal::Isolate*)
1 100.0% LazyCompile: ~normalizeString path.js:57:25
1 100.0% LazyCompile: ~resolve path.js:1075:28
1 100.0% LazyCompile: ~Module._initPaths internal/modules/cjs/loader.js:748:29
1 100.0% Script: ~<anonymous> internal/modules/cjs/loader.js:1:11
1 1.4% LazyCompile: ~participants.sort /home/haus/Desktop/Bostrom/Genetics/Selection.js:82:22
1 100.0% LazyCompile: ~InsertionSort native array.js:500:23
1 100.0% LazyCompile: ~QuickSort native array.js:531:19
1 100.0% LazyCompile: ~InnerArraySort native array.js:487:24
1 100.0% LazyCompile: ~sort native array.js:708:46
1 100.0% LazyCompile: module.exports.Tournament /home/haus/Desktop/Bostrom/Genetics/Selection.js:67:38
1 1.4% LazyCompile: module.exports.Tournament /home/haus/Desktop/Bostrom/Genetics/Selection.js:67:38
1 100.0% Script: ~<anonymous> /home/haus/Desktop/Bostrom/test.js:1:11
1 100.0% LazyCompile: ~Module._compile internal/modules/cjs/loader.js:650:37
1 100.0% LazyCompile: ~Module._extensions..js internal/modules/cjs/loader.js:698:37
1 100.0% LazyCompile: ~Module.load internal/modules/cjs/loader.js:590:33
1 100.0% LazyCompile: ~tryModuleLoad internal/modules/cjs/loader.js:535:23
1 1.4% /lib/x86_64-linux-gnu/libc-2.27.so
您可能会考虑的另一种算法:
在基准函数中对总体进行排序
保留锦标赛分组排序的伪代码:
//in tournamentSelection fucntion
var size_of_bucket= Math.floor(populationSize/tournamentSize)
for i=1;i<=size;i++
selected=population[Math.random() *((size_of_bucket*i)-(size_of_bucket*(i-1))]
这样你只需要排序一次
基本上这个算法是将人口分成桶(桶数 = 所需的锦标赛规模)。这样可以避免多次排序。
权衡:对于低迭代,这可能会导致花费的时间增加
Update :基于 jmrk 评论:将 parseInt 更改为 Math.floor 因为它更快
这里是 V8 开发人员。
您看到的主要是函数一个接一个优化的效果(与迭代计数本身影响每次迭代的时间相反)。您对此无能为力。这就是现代 JavaScript 引擎的工作原理。它真的会引起问题吗?
显示预热后性能相当一致的一种方法是颠倒预热案例的顺序。 (提示关于误导性微基准的通常提醒 ;-))
您编辑的分析结果很奇怪;我看到了一些不同的东西。也许你得到了错误的隔离?正如您假设的那样,排序是最昂贵的部分,大约花费了 60% 的时间。正如您正确观察到的那样,tournamentSize
越小,每次迭代越快。
Array.prototype.sort
是一个(高度优化的)内部内置,所以它的性能确实是你无法控制的。传入自定义比较器函数会产生显着的性能成本,但在这种情况下,我看不到解决方法。