JavaScript не работает стабильно (V8)
У меня есть следующий JavaScript, который выполняет выбор Турнира среди группы результатов.
// 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? Кроме того, любое предложение по улучшению производительности алгоритма будет высоко ценится.
Изменить: Вот журнал профилирования выполнения контрольного примера № 2 в среде NodeJS:
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
2 ответа
Разработчик V8 здесь.
То, что вы видите, это в основном эффект оптимизации функций одна за другой (в отличие от самого подсчета итераций, влияющего на время на каждую итерацию). На самом деле вы ничего не можете с этим поделать; так работают современные движки JavaScript. Это на самом деле вызывает проблемы?
Один из способов показать, что производительность остается достаточно стабильной после прогрева, - это изменить порядок случаев прогрева в обратном порядке. (Подайте обычное напоминание о вводящих в заблуждение микробенчмарках;-))
Результат профилирования в вашем редакторе странный; Я вижу что-то другое. Может быть, вы неправильно выбрали? Как вы и предполагали, сортировка - самая дорогая часть, на которую уходит около 60% времени. И, как вы правильно заметили, чем меньше вы делаете tournamentSize
чем быстрее каждая итерация.Array.prototype.sort
является (высоко оптимизированным) внутренним встроенным, так что его производительность действительно вне вашего контроля. Передача пользовательской функции компаратора требует значительных затрат производительности, но в этом случае я не вижу выхода из этого.
Другой алгоритм, который вы могли бы рассмотреть:
Сортировка населения в эталонной функции
Псевдокод для сохранения сортировки турнирной группы:
//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))]
Таким образом, вам нужно отсортировать только один раз
По сути, этот алгоритм делит население на ведра (номер ведра = требуемый размер турнира). Это позволит избежать сортировки несколько раз.
Компромисс: для низких итераций это может привести к увеличению времени
Обновление: на jmrk комментария jmrk: изменен parseInt на Math.floor, так как он намного быстрее