元の質問は2011年に尋ねられました。それ以来、Node.jsの台頭を考えると、問題を再検討する価値はあると思いました。サーバー環境では、ここ数ミリ秒で大したことがあります。それは負荷の下で応答する残りの間の違いかもしれません。
内部的な機能は概念的には優れていますが、JavaScriptエンジンのコードオプティマイザに問題が生じる可能性があります。次の例では、これを説明する:
function a1(n) {
return n + 2;
}
function a2(n) {
return 2 - n;
}
function a() {
var k = 5;
for (var i = 0; i < 100000000; i++) {
k = a1(k) + a2(k);
}
return k;
}
function b() {
function b1(n) {
return n + 2;
}
function b2(n) {
return 2 - n;
}
var k = 5;
for (var i = 0; i < 100000000; i++) {
k = b1(k) + b2(k);
}
return k;
}
function measure(label, fn) {
var s = new Date();
var r = fn();
var e = new Date();
console.log(label, e - s);
}
for (var i = 0; i < 4; i++) {
measure('A', a);
measure('B', b);
}
コードを実行するためのコマンド:
node --trace_deopt test.js
出力:あなたが見ることができるように
[deoptimize global object @ 0x2431b35106e9]
A 128
B 130
A 132
[deoptimizing (DEOPT eager): begin 0x3ee3d709a821 b (opt #5) @4, FP to SP delta: 72]
translating b => node=36, height=32
0x7fffb88a9960: [top + 64] <- 0x2431b3504121 ; rdi 0x2431b3504121 <undefined>
0x7fffb88a9958: [top + 56] <- 0x17210dea8376 ; caller's pc
0x7fffb88a9950: [top + 48] <- 0x7fffb88a9998 ; caller's fp
0x7fffb88a9948: [top + 40] <- 0x3ee3d709a709; context
0x7fffb88a9940: [top + 32] <- 0x3ee3d709a821; function
0x7fffb88a9938: [top + 24] <- 0x3ee3d70efa71 ; rcx 0x3ee3d70efa71 <JS Function b1 (SharedFunctionInfo 0x361602434ae1)>
0x7fffb88a9930: [top + 16] <- 0x3ee3d70efab9 ; rdx 0x3ee3d70efab9 <JS Function b2 (SharedFunctionInfo 0x361602434b71)>
0x7fffb88a9928: [top + 8] <- 5 ; rbx (smi)
0x7fffb88a9920: [top + 0] <- 0 ; rax (smi)
[deoptimizing (eager): end 0x3ee3d709a821 b @4 => node=36, pc=0x17210dec9129, state=NO_REGISTERS, alignment=no padding, took 0.203 ms]
[removing optimized code for: b]
B 1000
A 125
B 1032
A 132
B 1033
は、関数AとBが同じで走りました最初に速度。何らかの理由で最適化解除イベントが発生しました。それ以降、Bはほぼ一桁遅くなります。
パフォーマンスが重要なコードを書く場合は、内部機能を避けることが最善です。
。他の考慮点もあります。この例では、内部にある関数によって作成されるクロージャーは非常に貴重です。パラメーターとして渡したり、何かを再処理することなく、他のすべてのローカル変数をカプセル化できます。 – davin