如何优化/调试非常规的JavaScript代码

时间:2017-06-15 21:49:13

标签: javascript performance optimization

我正在尝试为lulz完成CodeWars挑战,但我似乎无法通过提交来获得高性能。解决方案是正确的,并通过了所有测试,但它未通过性能测试,采取> 120000毫秒

我的2个问题

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

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

  3. 详细要求可在此处找到: 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

    您应该能够将代码打到他们网站上的窗口中,并重新创建传递输入和失败的计时器测试。

3 个答案:

答案 0 :(得分:1)

你检查过chrome 59上的新工具吗?我认为他们有一些工具 https://github.com/awslabs/aws-sdk-ios-samples/tree/master/DynamoDBObjectMapper-Sample

答案 1 :(得分:0)

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

  2. 您的代码中有很多循环,试图找到避免它们的方法。特别是,你经常调用findDivisors(),它必须循​​环很大范围。如果您为了相同的号码重复拨打电话,memoization可以避免大部分内容。

答案 2 :(得分:0)

最快的循环方式是 循环。实际上它的接缝是while循环可以比循环更快。 您可以在此讨论What's the fastest way to loop through an array in JavaScript?

上查看有关循环性能的更多信息

使其更快的技巧是减少循环次数。每次调用map,reduce,filter,你的代码中有很多调用只是更好的for循环版本。

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

你应该看到很多好处,只需从findDivisor中删除范围调用和.filter,并更新find divisor to use(let i = 1; i< = x; i ++)