调用功能比直接调用要快吗?

时间:2018-09-10 03:23:46

标签: javascript

我使用“ Java忍者秘诀”中的脚本测试了性能:

function isPrime(number) {
  if (number < 2) {
    return false;
  }
  for (let i = 2; i < number; i++) {
    if (number % i === 0) {
      return false;
    }
  }
  return true;
}

console.time("isPrime");
isPrime(1299827);
console.timeEnd("isPrime");

console.time("isPrime");
isPrime.apply(1299827);
console.timeEnd("isPrime");

结果是:

isPrime: 8.276ms
isPrime: 0.779ms

似乎“申请”速度更快?

3 个答案:

答案 0 :(得分:5)

您的比较不准确,因为传递给apply的第一个参数是被调用函数的this值,传递给apply的第二个参数是一组参数,它们函数被调用。因此,您的apply不会使用任何参数调用isPrime,因此不会运行任何迭代,因为当i < number为2并且i时条件number不满足是undefined

function isPrime(number) {
  console.log('calling with ' + number);
  if (number < 2) {
    return false;
  }
  for (let i = 2; i < number; i++) {
    if (number % i === 0) {
      return false;
    }
  }
  return true;
}

console.time("isPrime");
isPrime(1299827);
console.timeEnd("isPrime");

console.time("isPrime");
isPrime.apply(1299827);
console.timeEnd("isPrime");

如果您正确使用apply并传递undefined, [1299827],则结果与预期的非常相似。您还应该使用performance.now()来获得优于console的毫秒级精度,尽管对于这样的快速操作,您可能看不到它们可能有所不同:

function isPrime(number){
    console.log('calling with ' + number);
    if(number < 2) { return false; }
    for(let i = 2; i < number; i++) {
        if(number % i === 0) { return false; }
    }
    return true;
}

const t1 = performance.now();
isPrime(1299827);
const t2 = performance.now();

isPrime.apply(undefined, [1299827]);
console.timeEnd("isPrime");
const t3 = performance.now();
console.log(t2 - t1);
console.log(t3 - t2);

答案 1 :(得分:2)

.apply的语法是

  

function.apply(thisArg,[argsArray])

在调用函数时,第一个参数thisArg指向'this'的值,在您的情况下,您在1299827中将isPrime.apply(1299827)传递为'this'但没有参数,因此它实际上是isPrime(),用于循环不会被执行,因此速度更快
有关更多信息。请在此处https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

答案 2 :(得分:2)

您必须阅读此书。

参考:https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

这是Array.prototype.apply(context = this, args = []),因此您的代码是错误的。

将您的代码更改为此。

// incorrect.
isPrime.apply(1299827);
// correct.
isPrime.apply(this, 1299827);