2015-08-30 33 views
0

功能問題來自postcss-discard-duplicates插件。這裏是index.js代碼:提高JS重複數據刪除功能的性能

'use strict'; 

var postcss = require('postcss'); 

function dedupe (node) { 
    if (node.nodes) { node.each(dedupe); } 

    if (node.type === 'comment') { return; } 

    var nodes = node.parent.nodes.filter(function (n) { 
     return String(n) === String(node); 
    }); 

    nodes.forEach(function (n, i) { 
     if (i !== nodes.length - 1) { 
      n.removeSelf(); 
     } 
    }); 
} 

module.exports = postcss.plugin('postcss-discard-duplicates', function() { 
    return function (css) { 
     css.each(dedupe); 
    }; 
}); 

插件使用PostCSS API返回CSS節點樹。完整的API有詳細記錄here

目前,我有大量的CSS文件建立在Twitter Bootstrap之上,並帶有許多複雜的選擇器。 CSS需要約37秒。如果使用此函數來查找並刪除任何重複的規則,則進行編譯。沒有它,這是〜3秒。

我正在尋找幫助優化此功能以獲得更好的性能。

更新:我發佈了複製函數作者所作改進的答案。它減少了超過50%的編譯時間。

+1

我想補充一下@Danila說,這大概是隻有輕微的性能提升,你可以通過優化此代碼來實現。當然,在大數據集上它可能會有所作爲。在詳細的結尾,你可以做的另外兩個優化是使用** for循環**而不是** forEach **。它有點快。你也可以做** toString **而不是** String **作爲** String **最終調用** toString **。 –

回答

0

reported this issue來回購業主和他提出了一些顯著的性能改進。我的編譯時間現在約13.5秒。 (加入討論評論中提及microoptimizations我也設法剃掉aditional的第二)

這是提高代碼:

'use strict'; 

var postcss = require('postcss'); 

function dedupe (node, index) { 
    if (node.type === 'comment') { return; } 
    if (node.nodes) { node.each(dedupe); } 

    var toString = node.toString(); 
    var nodes = node.parent.nodes; 
    var result = [node]; 
    var i = index + 1; 
    var max = nodes.length; 

    for (; i < max; i++) { 
     if (nodes[i].toString() === toString) { 
      result.push(nodes[i]); 
     } 
    } 

    for (var x = 0; x < result.length; x++) { 
     if (x !== result.length - 1) { 
      result[x].remove(); 
     } 
    } 

} 

module.exports = postcss.plugin('postcss-discard-duplicates', function() { 
    return function (css) { 
     css.each(dedupe); 
    }; 
}); 
0

我不確定是否很容易直接在這個函數中找到優化,看起來像是用於構建二叉樹等幫助結構的行業優化任務。這不是一個簡單的問題,算法中的問題,而不是實現中的問題。 如果您只想優化代碼 - 嘗試合併filterforEach。至少,這將有助於避免雙重迭代。

var last = null; 
var nodes = node.parent.nodes.forEach(function(n){ 
    if (String(n) === String(node)) { 
     if (last) { 
      last.removeSelf(); 
     } 
     last = n; 
    } 
});