В NodeJS я читаю и разбираю файл .txt, содержащий более 1,5 млн строк. Каждая строка имеет формат: date,number,number, где каждая дата - yyyyMMddhhmmss. Примерная строка:
20170506014255,100.01,200.02
Используя jFile, я могу прочитать и проанализировать все 1,5 миллиона строк примерно за 2 секунды ...
var jFile = require('jfile');
var data = [];
var dataFile = new jFile('./dataFile.txt');
dataFile.lines.forEach(function(line) {
data.push(line.split(','));
});
Работает отлично! Но я бы хотел изменить формат даты на другой. Для этого я использую Формат даты для преобразования ...
... same as previous, with new line within forEach() ...
var dateFormatter = require('date-format');
dataFile.lines.forEach(function(line) {
let tdata = line.split(',');
tdata[0] = dateFormatter('MM/dd/yy hh:mm:ss', dateFormatter.parse('yyyyMMddhhmmss', tdata[0]));
data.push(tdata);
});
Опять же, это отлично работает! Главным образом. То, что раньше занимало всего 2 секунды, теперь занимает около 25 секунд. Ох!
В идеале в файле должны быть правильно отформатированы даты, но это не в моих руках.
Есть ли более быстрый способ сделать это преобразование? Может есть более родной подход или просто более быстрый пакет?
Спасибо за понимание!



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я думаю, что быстрее жестко запрограммировать синтаксический анализ:
function fixFormat(date) {
const yy = date.slice(2, 4);
const MM = date.slice(4, 6);
const dd = date.slice(6, 8);
const hh = date.slice(8, 10);
const mm = date.slice(10, 12);
const ss = date.slice(12, 14);
return `${MM}/${dd}/${yy} ${hh}:${mm}:${ss}`;
}
Или действительно действительно некрасиво:
const y = 2, M = 4, d = 6, h = 8, m = 10, s = 12;
const pattern = fn => date => fn(p => date[p] + date[p + 1])
const fixFormat = pattern(p => p(M) + "/" + p(d) + "/" + p(y) + " " + p(h) + ":" + p(m) + ":" + p(s));
Может ли одно совпадение регулярного выражения быть быстрее, чем 6 последовательных вызовов .slice ()? Придется запустить несколько тестов. / [0-9] {2,2} ([0-9] {2,2}) ([0-9] {2,2}) ([0-9] {2,2}) ([0 -9] {2,2}) ( [0-9] {2,2}) ([0-9] {2, 2}) /
@ EricVautier - да, но регулярное выражение может быть намного проще в сочетании с совпадение. ;-)
Похоже, вы хотите поиграть в гольф-код, чтобы узнать, кто напишет для вас самый быстрый код.
Все, что анализирует строку, создает Date, а затем генерирует строку, если она будет медленнее, чем что-то, что просто переформатирует строку. Подход Йонаса верен и, вероятно, достаточно быстр, но все эти срезы должны сказаться на себе. Одно совпадение должно быть быстрее, но решать вам:
// Convert a timestamp in yyyyMMddhhmmss format to MM/dd/yy hh:mm:ss
// where "hh" is assumed to be 24 hr
function formatDate(s) {
var b = s.match(/\d\d/g);
return `${b[2]}/${b[3]}/${b[1]} ${b[4]}:${b[5]}:${b[6]}`;
}
console.info(formatDate('20170506014255'));Понятия не имею, быстрее ли это, но кода определенно намного меньше. Если вы действительно хотите сделать это быстро, создайте регулярное выражение один раз:
// Convert a timestamp in yyyyMMddhhmmss format to MM/dd/yy hh:mm:ss
// where "hh" is assumed to be 24 hr
var formatDate = (function() {
var re = /\d\d/g;
return function (s) {
var b = s.match(re);
return `${b[2]}/${b[3]}/${b[1]} ${b[4]}:${b[5]}:${b[6]}`;
};
}());
console.info(formatDate('20170506014255'));Нам просто нужен тест, чтобы увидеть, кто победит ... :)
@ JonasWilms — https://jsperf.com/reformat-date. Он идентифицировал MS Edge как Chrome 64. Похоже, строковые операции сильно оптимизированы. Если вы не используете Edge…
и я обязательно должен обновить свой Firefox ... следующая версия, похоже, удвоит общую скорость (или мой процессор просто медленный), однако это похоже на явную победу :)
Бум! Добавляет всего одну секунду времени обработки для всего набора. Я уверен, что все даты будут отформатированы одинаково, так что это идеальный вариант. Большое спасибо! Я все равно приму ваш ответ, но у вас есть
yyyyнаверху иyyв ответ. Я просто изменил первый синтаксический анализ наconst yy = date.slice(2, 4);, так как меня все равно интересуют только последние два символа. Хотя отличное исправление!