变量名称长度与性能

时间:2015-07-30 09:22:53

标签: javascript performance variables naming-conventions

如何可能,变量名称长度的巨大差异不会导致javascript中任何性能损失?

声明public function print_partner_invoice($partner_id, $echeance = 0) $partner = Partner::find($partner_id); // this return Collection of model $partner_resa = Partner::reservations_echeance($partner->id, $echeance); if(!$partner || $partner_resa->count() < 1) abort(403); $residence_company = $partner_resa->first()->residence->residence_company; $total_ttc = 0; $already_paid = 0; $tva_amount = 0; foreach ($partner_resa as $key => $resa) { foreach ($resa->stays as $key => $stay) { $amount = $stay->payment_due_date->total_amount; } } $pdf = \PDF::loadView('reglement.partner_invoice', [ 'partner' => $partner, 'resas' => $partner_resa, 'residence_company' => $residence_company, 'total_ttc' => $total_ttc, 'already_paid' => $already_paid, 'tva_amount' => $tva_amount ]); return $pdf->stream(); } 需要同样的时间来声明var a = 0; 即使用它们执行计算也需要相同的时间。

My fiddle to demonstrate

2 个答案:

答案 0 :(得分:6)

window.a = 2;
window.b = 3;
window.c = 4;
window.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = 2;
window.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = 3;
window.ccccccccccccccccccccccccccccccccccccccccccccccccc = 4;    
var ts = [];

var t = performance.now();
for(var i = 0; i < 1000000; ++i) {
    a = b + c;
}
ts.push(performance.now() - t);

var t = performance.now();
for(var i = 0; i < 1000000; ++i) {
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb+ ccccccccccccccccccccccccccccccccccccccccccccccccc;
}
ts.push(performance.now() - t);

console.log(ts);

在浏览器控制台中运行上述10次,给出了以下统计信息:a = b + c,a = b ... + c ...对:

[4.050000000046566, 4.614999999990687]
[4.254999999946449, 4.59499999997206]
[4.054999999993015, 4.584999999962747]
[4.869999999995343, 5.4500000000116415]
[4.074999999953434, 4.570000000006985]
[4.099999999976717, 4.775000000023283]
[4.205000000016298, 4.649999999965075]
[4.205000000016298, 4.669999999983702]
[4.159999999974389, 4.720000000030268]
[4.149999999965075, 4.684999999997672]

较长的版本始终较慢。

在局部变量的情况下,这是不同的,因为它们被编译一次并通过索引而不是名称使用getlocal / setlocal指令引用。所以,让我们看看..

(function() {
    var a = 2;
    var b = 3;
    var c = 4;
    var aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = 2;
    var bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = 3;
    var ccccccccccccccccccccccccccccccccccccccccccccccccc = 4;    
    var ts = [];

    var t = performance.now();
    for(var i = 0; i < 1000000; ++i) {
        a = b + c;
    }
    ts.push(performance.now() - t);

    var t = performance.now();
    for(var i = 0; i < 1000000; ++i) {
        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb+ ccccccccccccccccccccccccccccccccccccccccccccccccc;
    }
    ts.push(performance.now() - t);

    console.log(ts);
})();

[2.5850000000791624, 2.2100000000791624] (longer wins)
[2.7950000000419095, 2.525000000023283] (shorter wins)
[2.4699999999720603, 2.4200000000419095] (longer wins)
[2.64000000001397, 2.2449999999953434] (longer wins)
[2.669999999925494, 2.469999999855645] (longer wins)
[2.5200000000186265, 2.7800000000279397] (shorter wins)
[2.4600000000791624, 2.3950000000186265] (longer wins)
[3.2900000001536682, 3.1299999998882413] (longer wins)
[3.1949999999487773, 3.1850000000558794] (longer wins)
[3.8049999999348074, 3.0200000000186265] (longer wins)

虽然它们在大多数迭代中确实变化很大,但是在很多情况下,较长的变量名称比较短的变量名称更快(一个天真的观察者可能会得出结论,较长的名称使其更快)。这是因为名称仅在编译范围时相关;实际执行的指令不是按名称引用变量。

我的结论是;保持全局变量名称简短,局部变量名称将略微增加从文本到指令的转换,但在此之后,它无关紧要。

我假设javascript与actionscript的工作原理类似,它处理变量,所以这里是两个字节码的并行动作脚本转储。 (Adobe Flash CS3;使用JPEXS免费Flash反编译器反编译)。

var a;
var b = 2;
var c = 3;
var aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
var bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = 2;
var ccccccccccccccccccccccccccccccccccccccccccccccccc = 3;    

function long_global()
{        
    for(var i = 0; i < 1000000; ++i) {
        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + ccccccccccccccccccccccccccccccccccccccccccccccccc;
    }
}

function short_global()
{
    for(var i = 0; i < 1000000; ++i) {
        a = b + c;
    }
}

function long_local()
{        
    var aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
    var bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = 2;
    var ccccccccccccccccccccccccccccccccccccccccccccccccc = 3;

    for(var i = 0; i < 1000000; ++i) {
        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + ccccccccccccccccccccccccccccccccccccccccccccccccc;
    }
}

function short_local()
{
    var a;
    var b = 2;
    var c = 3;

    for(var i = 0; i < 1000000; ++i) {
        a = b + c;
    }
}

long_global编译为:

; d0
getlocal_0
; 30
pushscope
; 21
pushundefined
; 82
coerce_a
; d5
setlocal_1
; 24 00
pushbyte 0
; 82
coerce_a
; d5
setlocal_1
; 10 0e 00 00
jump ofs001b
; 09
ofs000d:label
; 5e 0a
findproperty Qname(PackageNamespace(""),"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
; 60 09
getlex Qname(PackageNamespace(""),"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
; 60 06
getlex Qname(PackageNamespace(""),"ccccccccccccccccccccccccccccccccccccccccccccccccc")
; a0
add
; 68 0a
initproperty Qname(PackageNamespace(""),"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
; d1
getlocal_1
; 91
increment
; 82
coerce_a
; d5
setlocal_1
; d1
ofs001b:getlocal_1
; 2d 01
pushint 1000000
; 15 eb ff ff
iflt ofs000d
; 47
returnvoid

short_global编译为

; d0
getlocal_0
; 30
pushscope
; 21
pushundefined
; 82
coerce_a
; d5
setlocal_1
; 24 00
pushbyte 0
; 82
coerce_a
; d5
setlocal_1
; 10 0e 00 00
jump ofs001b
; 09
ofs000d:label
; 5e 08
findproperty Qname(PackageNamespace(""),"a")
; 60 05
getlex Qname(PackageNamespace(""),"b")
; 60 04
getlex Qname(PackageNamespace(""),"c")
; a0
add
; 68 08
initproperty Qname(PackageNamespace(""),"a")
; d1
getlocal_1
; 91
increment
; 82
coerce_a
; d5
setlocal_1
; d1
ofs001b:getlocal_1
; 2d 01
pushint 1000000
; 15 eb ff ff
iflt ofs000d
; 47
returnvoid

long_local:

; d0
getlocal_0
; 30
pushscope
; 21
pushundefined
; 82
coerce_a
; d5
setlocal_1
; 21
pushundefined
; 82
coerce_a
; d6
setlocal_2
; 21
pushundefined
; 82
coerce_a
; d7
setlocal_3
; 21
pushundefined
; 82
coerce_a
; 63 04
setlocal 4
; 24 02
pushbyte 2
; 82
coerce_a
; d6
setlocal_2
; 24 03
pushbyte 3
; 82
coerce_a
; d7
setlocal_3
; 24 00
pushbyte 0
; 82
coerce_a
; 63 04
setlocal 4
; 10 0c 00 00
jump ofs002c
; 09
ofs0020:label
; d2
getlocal_2
; d3
getlocal_3
; a0
add
; 82
coerce_a
; d5
setlocal_1
; 62 04
getlocal 4
; 91
increment
; 82
coerce_a
; 63 04
setlocal 4
; 62 04
ofs002c:getlocal 4
; 2d 01
pushint 1000000
; 15 ec ff ff
iflt ofs0020
; 47
returnvoid

short_local:

; d0
getlocal_0
; 30
pushscope
; 21
pushundefined
; 82
coerce_a
; d5
setlocal_1
; 21
pushundefined
; 82
coerce_a
; d6
setlocal_2
; 21
pushundefined
; 82
coerce_a
; d7
setlocal_3
; 21
pushundefined
; 82
coerce_a
; 63 04
setlocal 4
; 24 02
pushbyte 2
; 82
coerce_a
; d6
setlocal_2
; 24 03
pushbyte 3
; 82
coerce_a
; d7
setlocal_3
; 24 00
pushbyte 0
; 82
coerce_a
; 63 04
setlocal 4
; 10 0c 00 00
jump ofs002c
; 09
ofs0020:label
; d2
getlocal_2
; d3
getlocal_3
; a0
add
; 82
coerce_a
; d5
setlocal_1
; 62 04
getlocal 4
; 91
increment
; 82
coerce_a
; 63 04
setlocal 4
; 62 04
ofs002c:getlocal 4
; 2d 01
pushint 1000000
; 15 ec ff ff
iflt ofs0020
; 47
returnvoid

long_global和short_global的字节码大小; short_local和long_local分别是equivelent,但在本地情况下,它们不是通过名称引用的,只能通过setlocal和getlocal引用;而在全局情况下,它们由字符串键所在的索引引用;我的猜测是,较长的一个需要更长的时间来散列来获取指示物,而较短的一个需要较短的时间才能使用它来获取指示物。

答案 1 :(得分:5)

基于@ Cerbrus的评论:

它在实践中导致可忽略小的性能差异,但仅在声明变量时。 之后,它会得到一个特定的address in the memory,它被称为此地址,而不是变量名称,因此它不再影响性能。

但是,谈到主要在Web上使用的脚本语言,较短的变量名称可以减少文件大小,并加快页面加载速度。这是JS编译器的一个特性,例如Google's