Доброго времени суток, уважаемые участники сообщества!
В книге Марейна Хавербека "Выразительный JavaScript" в качестве упражнения предложено написать функцию реверса массива, то есть нужно взять массив и перевернуть его, чтобы элементы, которые были в начале оказались в конце. Есть стандартный метод у массивов .reverse(), который выполняет эту функцию.
Данная задачу уже упоминалась среди вопросов, и был предложен ряд интересных решений.
Для тренировки решил задачу несколькими способами и решил проверить, сколько времени занимает каждый вариант.
Мной было реализовано 4 функции.
Первый вариант с помощью цикла While:
function reversInPlaceWhile(arr) {
var len = arr.length - 1;
var i = 0, temp;
while (i < len - i) {
temp = arr[i];
arr[i] = arr[len - i];
arr[len - i] = temp;
i++;
}
return arr;
}
Второй вариант с помощью цикла For
function reversInPlaceFor(arr) {
var len = arr.length - 1;
var temp;
for (var i = 0, iter = Math.floor(len / 2); i < iter; i++) {
temp = arr[i];
arr[i] = arr[len - i];
arr[len - i] = temp;
}
return arr;
}
Вариант третий, с использование стандартного метода:
function reversInPlaceStandart(arr) {
arr.reverse();
return arr;
}
Вариант четвертый, с помощью метода splice()
(этот вариант был предложен одним из участников сообщества)
function reversInPlaceSplice(arr) {
var len = arr.length - 1;
for (var i = 0; i < len; i++) {
arr.splice(i, 0, arr.pop());
}
return arr;
}
Для целей тестирования создал функцию, генерирующую простой массив нужного размера:
function newArrayLine(count) {
var arr = [];
for (var i = 0; i < count; i++) {
arr[i] = i;
}
return arr;
}
И наконец, для целей тестирования, я использовал функцию:
function test(arr, iter, callback) {
var start = Date.now();
for (var i = 0; i < iter; i++) {
callback(arr);
}
var end = Date.now();
return end - start;
}
где arr - это массив, который будет переворачивать
iter - количество раз, которые нужно переворачивать
callback - функция, с помощью которой будем переворачивать массив
Результат я ожидал получить в миллисекундах.
Запуская данную функцию на массиве 10 000 элементов, 100 раз, в браузере Mozilla Firefox, получил следующие результаты:
для функции с циклом
while: 1 мс;
для функции с циклом
for: 1 мс;
для функции с стандартным методом
reverse(): 12 мс;
для функции с методом
splice(): 6562 мс;
Запуская данную функцию на массиве 100 000 элементов, 100 раз, в браузере Chome, получил следующие результаты:
для функции с циклом
while: 7 мс;
для функции с циклом
for: 6 мс;
для функции с стандартным методом
reverse(): 25 мс;
для функции с методом
splice(): 485163 мс;
Запускал функции несколько раз, результаты примерно одинаковы.
Удивительно то, что встроенный метод работает медленнее, чем реализованные с циклами.
А теперь собственно основной вопрос: правильно ли проведено тестирование, и можно ли считать данные репрезентативными?
И еще один вопрос, нет ли в моем коде, каких-либо ошибок или недочетов, на которые мне следовало бы обратить внимание?
Заранее благодарен тем, кто решил уделить время моему вопросу!