Javascript For循环太慢
我有以下代码:Javascript For循环太慢,javascript,node.js,performance,for-loop,Javascript,Node.js,Performance,For Loop,我有以下代码: var Combinatorics = require('js-combinatorics'); var fs = require('fs'); cp = Combinatorics.cartesianProduct( ["4", "@", "/\\", "/-\\", "^", "∂", "λ", "α", "(!", "Z", "α"], ["1²", "2", "?", "P\\", "[\"/_", "l\"/_", "|-", "|2", "|?", "®",
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个单词,并将它们从新行保存到output.txt中
如果生成的单词数量不太多,则此代码运行速度很快,但在我的示例中,将生成411642个单词,并且我使用output.txt中的\n从换行符中编写它们。我使用这段代码的速度大约是82字/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也只写一次,你会有更好的性能,完全可以肯定
更新
我刚刚意识到您根本不需要循环,因为您所做的唯一事情就是为每个单词连接一个\n,您可以通过调用Array.prototype.join方法来实现这一点。在任何使用文件I/O的循环中,您首先要检查的是如何最小化文件操作,因为这通常比CPU任务慢几个数量级 这段代码在很多方面都是设计错误的。对于初学者来说,不要一次一个字地将每个字写入一个文件,每个字都调用fs.appendFile。打开文件一次。然后像流一样使用缓冲I/O进行写入,这样就不会对文件中的每一个字进行打开、写入和关闭操作。或者,将所有单词收集到一个数组中,然后立即将它们全部写入
此外,在一个for循环的中间放置一个异步操作,这会使系统过载,因为它不可能启动并执行许多异步操作,同时它们将最终被系统排队。
欢迎来到组合数学的世界。您将生成一个指数级增长的结果集。Javascript并不是这方面最快的语言。@EricJ。那么,我可以在这里使用什么最简单、最快的方法来获取我的单词列表呢?如果你使用console.log运行循环,删除它,它会使它更快。不知道为什么会有这么多的反对票,这是一个写得很好的问题,并且很清楚OP想要什么…@dandavis this console.log console.logcp.toArray[index],不是appendFile Callback中的那个谢谢,但是我怎样才能只打开一次文件?如何使用缓冲I/O?@cebit933-嗯,在循环之前打开文件。在循环过程中将所有单词收集到一个数组中,然后在循环结束时将它们全部写出并关闭文件。这是文件I/O的基础知识。您还可以使用文件流,它将为您提供缓冲区。