2017-06-15 112 views
0

我正试图完成lulz的CodeWars挑战,但我似乎无法获得足够的性能以通过提交。该解决方案是正确的,并通过了所有测试,但它未能通过性能测试,取> 120000毫秒如何优化/调试nonperformant javascript代码

我的2个问题FOR YOU

  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

你应该能够代码掴到窗口在他们的网站上,并重新创建通过输入和失败的计时器测试。

回答

0
  1. 要调试的性能问题,您可以使用profiler。它将帮助您识别花费时间最多的代码部分,以便您可以尝试改进它们。大多数浏览器在开发工具中都有一个内置的分析器。

  2. 你的代码中有很多循环,试图找到避免它们的方法。特别是,你经常打电话给findDivisors(),它必须在很大的范围内循环。如果你反复打电话给相同的号码,memoization可以避免很多。

0

最快循环的办法是变老变丑循环。事实上,它是接缝,而循环可以更快,然后循环。 您可以在此讨论中查看更多关于循环性能的信息What's the fastest way to loop through an array in JavaScript?

使其更快的技巧是减少循环次数。每一次调用映射,减少,过滤,并且在你的代码中有很多这样的调用只是更好的for循环版本。

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

你应该只通过删除findDivisor范围内的通话和.filter和更新的发现除数用于看到很多的好处(令i = 1;我< = X,我++)