2015-10-04 133 views
-6

我有以下代碼:For循環太慢

var Combinatorics = require('js-combinatorics'); 
var fs = require('fs'); 

cp = Combinatorics.cartesianProduct(
    ["4", "@", "/\\", "/-\\", "^", "∂", "λ", "α", "(!", "Z", "α"], ["1²", "2", "?", "P\\", "[\"/_", "l\"/_", "|-", "|2", "|?", "®", "12", "/2", "I2", "|^", "|~", "(r)", "|`", "l2", "Я", "ʁ", "я"], ["#", "(-)", ")-(", "/-/", "4", "<~>", "[-]", "\\-\\", "]-[", "]~[", "{-}", "{=}", "|-|", "|~|", "}{", ":-:", "}-{", "н"], ["!", "'", "1", "[]", "][", "|", "¦", "¡", ":", "]", "ι"], ["&", "3", "€", "£", "ë", "[-", "|=-", "ə", "ε"] 
); 

for(var index = 0; index < cp.length; ++index) { 
    //may be not the best idea, but in this way I will add new line to each word when saving them into array 
    var aux = cp.toArray()[index] + '\n'; 
    console.log(cp.toArray()[index]) 
    var contents = fs.appendFile("./output.txt", aux, 
     function(error) { 
      if(error) { 
       console.log("error writing"); 
      } 
     }); 
} 

它會生成411642分的話,將新生產線「\n」保存到output.txt的

此代碼的工作,如果快我沒有生成這麼多的單詞,但在我的情況下,要生成411642個單詞,並且我使用output.txt中的「\n」在換行符中編寫了它們。我使用此代碼的速度大約爲82字/ 1分鐘。它超級慢。我不明白爲什麼?我怎樣才能讓它快速?

+1

歡迎來到組合世界。您生成一個呈指數級增長的結果集。 Javascript並不是最快的語言。 –

+0

@EricJ。那麼,我可以在這裏使用獲取我的單詞列表的最簡單,最快捷的方式)? – cebit933

+0

如果您使用console.log運行循環,請將其刪除,它會使速度更快。 –

回答

1

你應該做一個字符串插值或創建一個數組,然後將值推送給它。

最後,您會追加整個字符串,或者使用Array.prototype.join將其轉換爲字符串。

for循環很快,問題就在於I/O。看看下面的例子:

var Combinatorics = require('js-combinatorics'); 
var fs = require('fs'); 

var cp = Combinatorics.cartesianProduct(
    ["4", "@", "/\\", "/-\\", "^", "∂", "λ", "α", "(!", "Z", "α"], 
    ["1²", "2", "?", "P\\", "[\"/_", "l\"/_", "|-", "|2", "|?", "®", "12", "/2", "I2", "|^", "|~", "(r)", "|`", "l2", "Я", "ʁ", "я"], 
    ["#", "(-)", ")-(", "/-/", "4", "<~>", "[-]", "\\-\\", "]-[", "]~[", "{-}", "{=}", "|-|", "|~|", "}{", ":-:", "}-{", "н"], 
    ["!", "'", "1", "[]", "][", "|", "¦", "¡", ":", "]", "ι"], 
    ["&", "3", "€", "£", "ë", "[-", "|=-", "ə", "ε"] 
); 

fs.appendFile('./output.txt', cp.toArray().join('\n'), function(error) { 
    if (error) 
    console.log('Error writing ' + error); 
}); 

注:另一件事我在這裏做緩存cp.toArray()到一個變量,所以你不需要每次循環迭代調用它一次。在做兩件事(寫入文件只有一次,並呼籲.toArray()只有一次要麼,你就會有一個更好的性能,完全肯定。


UPDATE

我剛剛意識到你根本不需要循環,因爲你所做的唯一事情是爲每個字連接一個\n,你可以通過調用Array.prototype.join方法來完成。

0

在任何使用文件I/O,幾乎是你想要檢驗的第一件事ne是如何最小化你的文件操作,因爲它通常比CPU任務慢幾個數量級。

此代碼只是設計錯誤的一堆方式。對於初學者,不要每個單詞一個單詞寫一個單詞,每個單詞只需要調用fs.appendFile()。打開文件一次。然後使用緩衝的I/O(如流)進行寫入,這樣您就不會爲每個單詞打開,寫入和關閉文件。或者,將所有單詞收集到一個數組中,然後將它們一次寫入。

此外,您正在將一個異步操作放在for循環的中間,這會使您的系統過載,因爲它不可能同時啓動並執行許多異步操作(它們最終會排隊由系統)。

+0

謝謝,但我怎樣才能打開文件一次?以及如何使用緩衝I/O? – cebit933

+0

@ cebit933 - 呃,在循環之前打開文件。在循環過程中將所有單詞收集到一個數組中,然後在循環結束時全部寫出並關閉文件。這是文件I/O基礎知識。你也可以使用文件流,它會爲你緩衝。 – jfriend00