kostik: (Default)
[personal profile] kostik

Не секрет, что спрос на приложения c приставкой “AJAX” постоянно растет. Волей-неволей приходится делать некоторые вещи неприспособленными для этого инструментами: характерным примером является Internet Explorer – программа, однозначно неприспособленная для выполнения кода, соответствующего стандарту и здравому смыслу. С одной из его проблем мне пришлось столкнуться: мне понадобилось отсортировать по заданному полю массив объектов. Выяснилось, что сортировка в IE работает в 100 раз медленнее, чем в FireFox. В результате было найдено решение, которое позволяет сортировать примерно в 6 раз быстрее, чем это делает Internet Explorer, ниже есть ссылка на библиотеку, которая реализует этот метод.

Проблема

Тривиальное

// Object а содержит 15000 элементов
a.sort(function(a, b){return b.item – a.item;})

заставило IE задуматься на 40(!) секунд (15000 взято в качестве теста, реальный массив, конечно, меньше). (FireFox выполнял тот же за 422ms, примерно в 100 раз быстрее!) Реализация сортировки на стороне сервера потребовала бы изменить много кода, так как поле и направление сортировки выбирались пользователем произвольно; это была проблема.

Решение

После недолгих поисков я обнаружил отличную статью Russel Lindsay: “Faster Javascript sorting”. Он использует очень простую вещь: переписать метод toString() для обращения к свойству объекта, превратить числа в строки ([1, 2, 10] в [’01’,’02’,’10’]) и использовать sort() без параметров для ускорения поиска. Вот результаты тестов:

Internet Explorer
41516ms – sort(function(a, b){return b.item - a.item;})
7031ms - sort() для массива, где числа конвертированы в строки
7047ms – sort() и reverse() для массива, где числа конвертированы в строки

FireFox
438ms – sort(function(a, b){return b.item - a.item;})
891ms - sort() для массива, где числа конвертированы в строки
954ms – sort() и reverse() для массива, где числа конвертированы в строки

Таким образом, фокус с дополнением чисел нолями до строк дает выигрыш примерно в 6 раз при сортировке в Internet Explorer, и проигрыш всего вдвое при сортировке в FF, что позволяет использовать код в обоих браузерах.

Russel Lindsay использует маску фиксированного размера, то есть массив ([1, 2, 10] превращается не в [01, 02, 10], а в [’00000000001’,’ 00000000002’,’ 00000000010’]), это ужасно по многим причинам, и память – не последняя из них. Так что я написал маленькую библиотеку на основе его кода, она расширяет Array() методами Array.sortIntAsc(property) и Array.sortIntDesc(property) для сортировки по числовому полю property, и методами Array.sortAsc(property) и Array.sortDesc(property) для сортировки по строковому полю property.

Пример

[js] var team = [
{name:'Bill', age:25},
{name:'John', age:21},
{name:'Ann', age:20}
];

alert([team[0].name,team[1].name,team[2].name]);
// Bill, John, Ann

team.sortIntAsc(‘age’);
alert([team[0].name,team[1].name,team[2].name]);
// Ann, John, Bill

team.sortAsc(‘name’);
alert([team[0].name,team[1].name,team[2].name]);
// Ann, Bill, John

[/js]

Мои 5 копеек

Этот метод, мне кажется, неплохое решение конкретной проблемы. Но это так же прекрасная иллюстрация: лучший способ сделать что-то с данными в Internet Explorer – это не делать совсем, то есть организовать модель так, что бы вся обработка данных (включая сортировку) осталась на стороне сервера. Иначе потом, когда IE будет отвратительно справляться с очевидными задачами, придется потратить немало сил на обход проблемы.

скачать библиотеку

http://blog.piterpen.net/2007/01/08/%d0%b1%d1%8b%d1%81%d1%82%d1%80%d0%b0%d1%8f-%d1%81%d0%be%d1%80%d1%82%d0%b8%d1%80%d0%be%d0%b2%d0%ba%d0%b0-%d0%b2-javascript/

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

April 2016

S M T W T F S
     12
3456789
10111213141516
17181920212223
2425 26 27 282930

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 8th, 2025 01:37 am
Powered by Dreamwidth Studios