2015-10-04 3 views
-6

У меня есть следующий код:Для цикла слишком медленно

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 слова, которые должны быть сгенерированы, и я написал их из новой строки, используя «\n» в файле output.txt. Моя скорость с использованием этого кода приблизительно равна 82 словам/1 минута. Это очень медленно. Я не понимаю, почему? Как я могу сделать это быстро?

+1

Добро пожаловать в мир комбинаторики. Вы создаете экспоненциально растущий набор результатов. Javascript - это не самый быстрый язык для этого. –

+0

@EricJ. Так что я могу использовать здесь самый простой и быстрый способ получить мой список слов)? – cebit933

+0

Если вы используете цикл с console.log, удалите его, это сделает его намного быстрее. –

ответ

1

Вы должны сделать строчную интерполяцию или создать массив, а затем нажать на него значения.

В конце вы должны добавить всю строку или использовать Array.prototype.join, чтобы включить ее в строку.

Цикл for быстр, проблема в том, что входы/выходы. Посмотрите на примере ниже:

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 - как свести к минимуму ваши файловые операции, потому что это, как правило, на несколько порядков медленнее задач ЦП.

Этот код просто разработан неправильно с помощью пута. Для начала не записывайте каждое слово в файл по одному слову за раз с fs.appendFile(), вызываемым для каждого слова. Откройте файл один раз. Затем используйте буферизованный ввод-вывод (например, поток) для записи, чтобы вы не открывали, не писали, не закрывали файл для каждого слова. Или, соберите все слова в массив, а затем напишите их сразу.

Кроме того, вы выполняете операцию async в середине цикла for, который будет перегружать вашу систему, поскольку она не может запускаться и выполнять много операций async одновременно (они будут в конечном итоге попадать в очередь системой).

+0

Спасибо, но как я могу открыть файл только один раз? и как я могу использовать буферизованный ввод-вывод? – cebit933

+0

@ cebit933 - Uh, откройте файл перед вашей петлей.Соберите все слова в массив во время цикла, затем напишите их все в конце цикла и закройте файл. Это основные файлы ввода-вывода. Вы также можете использовать потоки файлов, которые будут буферизованы для вас. – jfriend00

Смежные вопросы