Ответ 1
На основе этой настройки:
var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
var length = array.length;
Array.reverse();
является первым или вторым самым медленным!
Тесты здесь: http://jsperf.com/js-array-reverse-vs-while-loop/5
Во всех браузерах swap-контуры быстрее. Существует два общих типа алгоритмов подкачки (см. Wikipedia), каждый из которых имеет два варианта.
Двумя типами подкатегорий являются временный своп и сводка XOR.
Два варианта обрабатывают индексные вычисления по-разному. Первая вариация сравнивает текущий левый индекс и правый индекс, а затем уменьшает правый индекс массива. Вторая вариация сравнивает текущий левый индекс и длину, разделенную на половину, а затем пересчитывает правый индекс для каждой итерации.
Вы можете увидеть или не увидеть огромные различия между этими двумя вариантами. Например, в Chrome 18 первые варианты временного свопа и замены XOR на 60% медленнее, чем во втором варианте, но в Opera 12 оба варианта временного свопа и обмена XOR имеют схожую производительность.
Временная свопа:
Первая вариация:
function temporarySwap(array)
{
var left = null;
var right = null;
var length = array.length;
for (left = 0, right = length - 1; left < right; left += 1, right -= 1)
{
var temporary = array[left];
array[left] = array[right];
array[right] = temporary;
}
return array;
}
Вторая вариация:
function temporarySwapHalf(array)
{
var left = null;
var right = null;
var length = array.length;
for (left = 0; left < length / 2; left += 1)
{
right = length - 1 - left;
var temporary = array[left];
array[left] = array[right];
array[right] = temporary;
}
return array;
}
XOR swap:
Первая вариация:
function xorSwap(array)
{
var i = null;
var r = null;
var length = array.length;
for (i = 0, r = length - 1; i < r; i += 1, r -= 1)
{
var left = array[i];
var right = array[r];
left ^= right;
right ^= left;
left ^= right;
array[i] = left;
array[r] = right;
}
return array;
}
Вторая вариация:
function xorSwapHalf(array)
{
var i = null;
var r = null;
var length = array.length;
for (i = 0; i < length / 2; i += 1)
{
r = length - 1 - i;
var left = array[i];
var right = array[r];
left ^= right;
right ^= left;
left ^= right;
array[i] = left;
array[r] = right;
}
return array;
}
Существует еще один метод подкачки, называемый назначением деструктуризации: http://wiki.ecmascript.org/doku.php?id=harmony:destructuring
Назначение деструктуризации:
Первая вариация:
function destructuringSwap(array)
{
var left = null;
var right = null;
var length = array.length;
for (left = 0, right = length - 1; left < right; left += 1, right -= 1)
{
[array[left], array[right]] = [array[right], array[left]];
}
return array;
}
Вторая вариация:
function destructuringSwapHalf(array)
{
var left = null;
var right = null;
var length = array.length;
for (left = 0; left < length / 2; left += 1)
{
right = length - 1 - left;
[array[left], array[right]] = [array[right], array[left]];
}
return array;
}
В настоящее время алгоритм, использующий назначение деструктуризации, является самым медленным из всех. Он еще медленнее, чем Array.reverse();
. Однако алгоритмы, использующие назначения деструктурирования и методы Array.reverse();
, являются кратчайшими примерами, и они выглядят чище. Я надеюсь, что их производительность улучшится в будущем.
Еще одно упоминание о том, что современные браузеры улучшают производительность массивов push
и splice
.
В Firefox 10 этот алгоритм цикла for
с использованием массива push
и splice
конкурирует с алгоритмами временного свопинга и XOR-подкачки.
for (length -= 2; length > -1; length -= 1)
{
array.push(array[length]);
array.splice(length, 1);
}
Однако вы, вероятно, должны придерживаться алгоритмов цикла подкачки, пока многие из других браузеров не совпадают или не превысят производительность своего массива push
и splice
.