Пусть у нас есть массив чисел
1 |
var numbers:Array = [2, 7, 4, 9, 12, 6, 13, 19]; |
и стоит задача найти максимальное или минимальное число из тех, которые находятся в этом массиве. Первое что приходит на ум, это перебрать массив и найти элемент с максимальным (минимальным) значением. Но есть и другой путь.
Все знают функции Math.min() и Math.max(), которые используются для оценки переданных аргументов и определения минимального и максимального из них. Эти функции могут принимать несколько аргументов. Вспомнив, как работает метод apply() у Function легко додуматься до следующего способа нахождения минимального и максимального числа из массива:
1 2 |
var min:Number = Math.min.apply(null, numbers); var max:Number = Math.max.apply(null, numbers); |
Это неплохой способ сократить код, такая запись намного короче перебора в цикле. Но остаётся ещё один вопрос — производительность.
Тест производительности
Сравним Math.min() с реализацией перебором:
1 2 3 4 5 6 7 8 9 |
var min:Number = NaN; var i:uint; var num:Number; var count:uint = numbers.length; for (i = 0; i < count; ++i) { num = numbers[i]; if (isNaN(min) || min > num) min = num; } |
Массив чисел сгенерирован случайным образом и содержит 20 элементов, поиск элементов выполняется 1000000 раз. Итак, результаты:
1 2 3 |
Numbers: 128,-332,-280,-250,-89,328,91,-279,163,-141,-186,-187,98,-18,-102,-363,-161,-338,-7,342 [Math.min()] Result: -363 Time: 992 ms [for(;;){ }] Result: -363 Time: 7266 ms |
Как видно, минимум оба метода выдают одинаковый, но реализация перебором при этом работает медленнее. Отмечу, что с увеличением размера массива разница увеличивается. Это логично, ведь при использовании Math.min() перебор элементов происходит нативно, внутри FlashPlayer’а и можно было предположить что такой перебор быстрее цикла в as3.
Таким образом мы имеем более простой и более быстрый метод нахождения минимального или максимального значения в массиве чисел.
В конце полезные ссылки: