Подтвердить что ты не робот

Fs.readFileSync кажется быстрее, чем fs.readFile - нормально ли использовать его для создания веб-приложения?

Я знаю, что при разработке в node вы всегда должны стараться избегать блокировки (синхронизации) и работать с асинхронными функциями, однако я немного тестирую, как они сравниваются.

Мне нужно открыть json файл, содержащий данные i18n (например, формат даты и времени и т.д.) и передать эти данные классу, который использует эти данные для форматирования чисел и т.д. в моих представлениях.

Было бы неловко начать обматывать все методы класса внутри обратных вызовов, поэтому, если это возможно, я бы использовал вместо него синхронную версию.

console.time('one');
console.time('two');
fs.readFile( this.dir + "/" + locale + ".json", function (err, data) {
  if (err) cb( err );
  console.timeEnd('one');
});
var data = fs.readFileSync( this.dir + "/" + locale + ".json" );
console.timeEnd('two');

Это приводит к следующим строкам в моей консоли:

two: 1ms
one: 159ms

Кажется, что fs.readFileSync примерно в 150 раз быстрее, чем fs.readFile, и занимает около 1 мс, чтобы загрузить файл размером 50 КБ json (minified). Все мои файлы json составляют около 50-100 КБ.

Я тоже думал, может быть, каким-то образом запоминаю или сохраняю эти данные json на сеанс, чтобы файл читался только один раз за сеанс (или когда пользователь меняет свой локаль). Я не совсем уверен, как это сделать, это просто идея.

Можно ли использовать fs.readFileSync в моем случае или я получу проблемы позже?

4b9b3361

Ответ 1

Нет, не следует использовать вызов API блокировки на сервере node, как вы описываете. Ваш сайт реагирует на многие параллельные соединения, будет иметь огромный успех. Он также просто грубо нарушает принцип №1 node.

Ключом к работе node является то, что пока он ожидает ввода-вывода, он одновременно обрабатывает процессор/память. Это требует исключительно асинхронных вызовов. Поэтому, если у вас 100 клиентов, читающих 100 файлов JSON, node может попросить ОС прочитать эти 100 файлов, но, ожидая, пока ОС вернет данные файла, когда она будет доступна, node может обрабатывать другие аспекты этих 100 сетевых запросов. Если у вас есть один синхронный вызов, вся обработка вашего клиента полностью прекращается, пока эта операция завершается. Таким образом, клиентское соединение номер 100 ждет без обработки вообще, пока вы читаете файлы для клиентов 1, 2, 3, 4 и т.д. Последовательно. Это Failville.

Здесь другая аналогия. Если бы вы отправились в ресторан и были единственным клиентом, вы, вероятно, получили бы более быструю услугу, если бы один человек сидел с вами, принимал ваш заказ, готовил его, подавал его вам и обрабатывал законопроект без затрат на координацию работы с хостом/хостесс, сервер, шеф-повар, повара, кассиры и т.д. Однако, со 100 клиентами в ресторане, дополнительная координация означает, что все происходит параллельно, а общая отзывчивость ресторана увеличивается намного дальше того, что было бы, если бы один человек был пытаясь обрабатывать 100 клиентов самостоятельно.

Ответ 2

Вы блокируете обратный вызов асинхронного чтения с помощью синхронного чтения, помните одиночный поток. Теперь я понимаю, что разница во времени все еще удивительна, но вы должны попробовать с файлом, который намного, гораздо дольше, чтобы читать и воображать, что многие, многие клиенты будут делать то же самое, только тогда накладные расходы окупятся. Это должно ответить на ваш вопрос, да, у вас возникнут проблемы, если вы будете обслуживать тысячи запросов с блокировкой IO.

Ответ 3

Я попытался проверить реальное, измеримое различие в скорости между fs.readFileSync() и fs.readFile() для загрузки 3 разных файлов, которые находятся на SD-карте, и я добавил между этими загрузками некоторый математический расчет и я не понимаю, где разница в скорости, которая всегда отображается на снимках node, когда node быстрее и просто работает, например, загружая 3 раза один и тот же файл, и время для этой операции близко к времени, которое необходимо загрузить 1 раз этот файл.

Я понимаю, что это, без сомнения, полезно, что сервер при загрузке какого-либо файла способен выполнять другую работу, но много времени на youtube или в книгах есть некоторые диаграммы, которые не точны, потому что, когда у вас есть такая ситуация, как ниже async node работает медленнее, а затем синхронизируется при чтении небольших файлов (например, ниже: 85kB, 170kB, 255kB).

var fs = require('fs');

var startMeasureTime = () => {
  var start = new Date().getTime();
  return start;
};

// synch version
console.log('Start');
var start = startMeasureTime();

for (var i = 1; i<=3; i++) {
  var fileName = `Lorem-${i}.txt`;
  var fileContents = fs.readFileSync(fileName);
  console.log(`File ${1} was downloaded(${fileContents.length/1000}KB) after ${new Date().getTime() - start}ms from start.`);

  if (i === 1) {
    var hardMath = 3*54/25*35/46*255/34/9*54/25*35/46*255/34/9*54/25*35/46*255/34/9*54/25*35/46*255/34/9*54/25*35/46*255/34/9;  
  };
};

// asynch version
setImmediate(() => {
  console.log('Start');
  var start = startMeasureTime();

  for (var i = 1; i<=3; i++) {
    var fileName = `Lorem-${i}.txt`;
    fs.readFile(fileName, {encoding: 'utf8'}, (err, fileContents) => {
      console.log(`File ${1} was downloaded(${fileContents.length/1000}KB) after ${new Date().getTime() - start}ms from start.`);
    });

    if (i === 1) {
      var hardMath = 3*54/25*35/46*255/34/9*54/25*35/46*255/34/9*54/25*35/46*255/34/9*54/25*35/46*255/34/9*54/25*35/46*255/34/9;  
    };
  };
});

This is from console:
Start
File 1 was downloaded(255.024KB) after 2ms from start.
File 1 was downloaded(170.016KB) after 5ms from start.
File 1 was downloaded(85.008KB) after 6ms from start.
Start
File 1 was downloaded(255.024KB) after 10ms from start.
File 1 was downloaded(85.008KB) after 11ms from start.
File 1 was downloaded(170.016KB) after 12ms from start.