如何优化/调试非高性能的JavaScript代码



我正在尝试为lulz完成CodeWars挑战,但我似乎无法使其性能足以通过提交。该解决方案是正确的,并通过了所有测试,但未能通过性能测试,需要 120000 毫秒>

我给你的两个问题

  1. 某人如何调试性能问题?我不知道如何开始调试性能并识别非性能代码,或者如何有意优化代码

  2. 此特定代码有什么问题?是否存在我执行不正确的模式?代码的某些部分是否发生太多次?

详细要求可在此处找到: https://www.codewars.com/kata/integers-recreation-one ```

//generate an array of range, containing every number M to N
//map1: for each  number find all divisors
//map2: for each array of divisors, format answer for tests
//filter out undefined results
let listSquared = (m, n) => range(m,n)
.map(nextNumberInRange => findDivisors(nextNumberInRange))
.map(arrayOfDivisors => formatAnswer(
arrayOfDivisors[arrayOfDivisors.length - 1],
squareAndSumAll(arrayOfDivisors)))
.filter(x => x !== undefined)

//if the square root of y (the sum of squared divisors) is WHOLE, return [x,y]
let formatAnswer = (x,y) => Math.sqrt(y) % 1 === 0 ? [x,y] : undefined
//find all divisors of any integer
let findDivisors = (x) => range(1,x).filter(y => x%y === 0 || y===x)
//generate an array containing values from start to end.
//e.g. 100-500, 351-293487 etc. 
let range = (start,end) => [...Array((end-start)+1)].map((x,i)=> start+i)

let squareAndSumAll = (x) => x.map(square).reduce(add)
let add = (x,y) => x + y
let square = (x) => x * x

详细要求可在此处找到: https://www.codewars.com/kata/integers-recreation-one

您应该能够将代码插入其网站上的窗口,并重新创建通过的输入和失败的计时器测试。

  1. 若要调试性能问题,请使用探查器。它将帮助您确定代码中花费最多时间的部分,因此您可以尝试改进它们。大多数浏览器在开发人员工具中都有内置探查器。

  2. 你的代码中有很多循环,试着找到一种方法来避免它们。特别是,您经常调用findDivisors(),并且它必须在很大的范围内循环。如果你重复调用相同的数字,记忆可以避免很多这种情况。

最快的循环方式是老丑陋的循环。实际上,接缝是 while 循环可以比 for 循环更快。 您可以在此讨论中查看有关循环性能的更多信息 在 JavaScript 中循环数组的最快方法是什么?

使其更快的诀窍是减少循环次数。 每次调用映射、减少、过滤,并且代码中有很多这样的调用只是更好的慢速版本的 for 循环。

  • 4 个映射调用,1 个化简,2 个过滤器(总共 7 个循环)我的第一个赌注是减少循环次数。在 1 个循环周期内执行多个操作。

通过从 findDivisor 中删除范围调用和 .filter 并更新要用于的查找除数,您应该会看到很多好处(let i = 1; i <= x; i++)