2017-06-15 162 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,我++)