gpt4 book ai didi

javascript - 分析性能敏感的代码路径

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:41:51 25 4
gpt4 key购买 nike

我有一个函数接收 2 个参数和 1 个额外的可选参数。如果第一个参数大于第二个参数,函数必须返回 true,否则返回 false,除非第三个参数为 true(第三个参数只能为 true 或 false,默认情况下为 false),在这种情况下,如果第一个参数大于或等于(严格比较)第二个参数,则函数应返回 true。

该函数不保证接收相同类型的参数,甚至不保证任何有意义的参数(可以使用 null, undefined 调用该函数)。无论如何,该函数必须遵循 javascript 行为来比较接收到的参数。

我有两个函数,我相信第二个应该更快,但我自己的基准测试和 jsperf results 都不是这样说的。事实上,第一个函数快了大约 30-35%,这是相当多的。

如何追踪每个函数内的慢速代码路径?我怎么知道为什么第二个函数比较慢?

这是我的基准:

var microtime = require('microtime');

/* Helper functions */

function maybeBool() {
if(Math.round(Math.random() * 1)) {
return true;
} else {
return false;
}
}

function maybeNullUndef() {
if(Math.round(Math.random() * 1)) {
return null;
} else {
return undefined;
}
}

function randomString() {
return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
}

function randomDate() {
var y = Math.round(Math.random() * 100);
return new Date(y);
}

function something() {
var x = Math.round(Math.random()*3);

switch(x) {
case 0:
return maybeBool();
break;

case 1:
return maybeNullUndef();
break;

case 2:
return randomString();
break;

case 3:
return randomDate();
break;
}
}

var things_to_compare = [];

for(i = 0; i < 500000; i++) {
var a = something();
var b = something();
things_to_compare.push([a, b]);
}

/* First function */

function gtHelper(prop1, prop2, equal) {

// 'falsy' and Boolean handling
if (!prop1 || !prop2 || prop1 === true || prop2 === true) {
if ((prop1 === true || prop1 === false) && (prop2 === true || prop2 === false)) {
if (equal) {
return prop1 === prop2;
} else {
if (prop1) {
return !prop2;
} else {
return false;
}
}
}

if (prop1 === undefined || prop1 === null || prop1 === false || prop2 === true) {
return !!equal || false;
}
if (prop2 === undefined || prop2 === null || prop1 === true || prop2 === false) {
return true;
}

if (prop1 > prop2) {
return true;
}

if (prop1 < prop2) {
return false;
}

// not lt and and not gt so equality assumed-- this ordering of tests is date compatible
return equal;
}

if (prop1 > prop2) {
return true;
}

if (prop1 < prop2) {
return false;
}

// not lt and and not gt so equality assumed-- this ordering of tests is date compatible
return equal;
}


/* Second function */

function gtHelper2 (prop1, prop2, equal) {

equal = !!equal;

//If 'prop1' is any of those, the result will be always 'false',
//unless 'equal' is true.
switch (prop1) {
case "":
case null:
case false:
case undefined:
return (prop1 === prop2 && equal);
}

//If 'prop2' is any of those, the result will be always 'true'
switch (prop2) {
case "":
case null:
case false:
case undefined:
return true;
}

if (prop1 > prop2 || (prop1 === prop2 && equal)) {
return true;
} else if (prop1 < prop2) {
return false;
} else {
return equal;
}
}

/* Benchmark */

var res1 = 0;
for(n = 0; n < 30; n++) {
var now = microtime.now();
for(i = 0; i < 500000; i++) {
gtHelper(things_to_compare[i][0], things_to_compare[i][1]);
}
var now1 = microtime.now();

res1 += now1 - now;
}



var res2 = 0;
for(n = 0; n < 30; n++) {
var now = microtime.now();
for(i = 0; i < 500000; i++) {
gtHelper2(things_to_compare[i][0], things_to_compare[i][1]);
}
var now1 = microtime.now();

res2 += now1 - now;
}

console.log("gtHelper:", res1/30);
console.log("gtHelper2:", res2/30);

编辑:

我一直在进一步研究第二个功能,我实现了让它更快一点,但它一直落后于第一个功能。

现在是这样的:

function gtHelper2 (prop1, prop2, equal) {

//If 'prop1' is any of those, the result will be always 'false',
//unless 'equal' is true.
if (!prop1) {
return (prop1 === prop2 && !!equal);
}

//If 'prop2' is any of those, the result will be always 'true'
if (!prop2) {
return true;
}

if (prop1 > prop2) {
return true;
} else if (prop1 < prop2) {
return false;
} else if (prop1 === prop2 && !!equal) {
return true;
} else {
return !!equal;
}
}

最佳答案

你的两个函数不返回相同的东西。

gtHelper(true, 'string')         // true
gtHelper2(true, 'string') // false

gtHelper('string', new Date()) // undefined
gtHelper2('string', new Date()) // false

gtHelper(new Date(), 'string') // undefined
gtHelper2(new Date(), 'string') // false

如果您能让这些函数表现相同,我相信您会看到更有意义的结果。

您应该知道,至少在浏览器中,您不应期望 switch 在所有平台上执行相同的操作。您应该阅读 ECMA specswitch 上查看为什么优化它如此困难。我知道 Firefox 确实花了很多时间来使他们的 switch 实现表现良好。我在 V8 上没有听说过任何类似的事情。

关于javascript - 分析性能敏感的代码路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35689181/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com