Ваши тесты не измеряют так же, как в первом тесте вы тратите время на создание нового ArrayBuffer, а во втором тесте строка «уже определена в памяти», поэтому она дешевле.
Iсоздали тест с разными числами даты (рандомизированными), создали буфер и строку для тех же чисел ДО запуска таймера.Струны еще быстрее, но меньше.Это результат:
![enter image description here](https://i.stack.imgur.com/rJryj.png)
var SIZE = 100000;
var dates = [];
for (var i = 0; i < SIZE; i++) {
var buf = new ArrayBuffer(14);
var str = "";
buf[0] = Math.floor(Math.random()*10);
buf[1] = Math.floor(Math.random()*10);
buf[2] = Math.floor(Math.random()*10);
buf[3] = Math.floor(Math.random()*10);
buf[4] = Math.floor(Math.random()*10);
buf[5] = Math.floor(Math.random()*10);
buf[6] = Math.floor(Math.random()*10);
buf[7] = Math.floor(Math.random()*10);
buf[8] = Math.floor(Math.random()*10);
buf[9] = Math.floor(Math.random()*10);
buf[10] = Math.floor(Math.random()*10);
buf[11] = Math.floor(Math.random()*10);
buf[12] = Math.floor(Math.random()*10);
buf[13] = Math.floor(Math.random()*10);
for (var ii = 0; ii < 14; ii++) {
str += buf[ii];
}
dates.push({buf, str});
}
function convertDateTimeToFormatBuf(date, format) {
var buf = new ArrayBuffer(14);
var result = new Uint8Array(buf);
var positions = {
y: 0,
M: 4,
d: 6,
H: 8,
m: 10,
s: 12
};
for (var index = 0; index < 14; index++) {
result[index] = date[positions[format[index]]++];
}
return result;
}
function convertDateTimeToFormatStr(date, format) {
var result = "";
var positions = {
y: 0,
M: 4,
d: 6,
H: 8,
m: 10,
s: 12
};
for (var index = 0; index < 14; index++) {
result += date[positions[format[index]]++];
}
return result;
}
console.time("Buffer");
for (i = 0; i < SIZE; i++) {
convertDateTimeToFormatBuf(dates[i].buf, "MMddyyyyHHmmss");
}
console.timeEnd("Buffer");
console.time("String");
for (i = 0; i < SIZE; i++) {
convertDateTimeToFormatStr(dates[i].str, "MMddyyyyHHmmss");
}
console.timeEnd("String");
V8 значительно оптимизирован при объединении строк.У вас есть фиксированный цикл с простой конкатенацией строк, поэтому V8 оптимизирует его довольно хорошо, поскольку он знает, что на самом деле происходит внутри цикла.Я предполагаю, что конкатенация строк в памяти не произойдет, пока цикл не завершится, что будет довольно быстро.
С буферами все по-другому.Вы ничего не объединяете, так как вы просто получаете доступ к позициям памяти (хотя вы делаете это последовательно), но ожидайте, что при каждой позиции, которую вы устанавливаете, запись в память происходит мгновенно (без какой-либо оптимизации).Все это с накладными расходами, которые означают запись в массив uint8.
Типизированные массивы предполагают, что к памяти осуществляется прямой доступ, как это происходит в C и т. П., Но в типизированных JavaScript-массивах издержки намного больше, чем в строке, как вы можетечитайте здесь: https://stackoverflow.com/a/45808835/1525495