Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Сортировка в векторе с элементами null (http://www.flasher.ru/forum/showthread.php?t=156222)

semenyakinVS 18.05.2011 13:37

Сортировка в векторе с элементами null
 
Обнаружил достаточно забавный факт.
Есть, например, вот такой код:

Код AS3:

var valVect:Vector.<ListEl> = new Vector.<ListEl>();
 
var findCount:int = 500; // Задаём количество не null элементов из общего количества 3000
 
for(i = 0 ; i < findCount ; i++)
{
        valVect.push(new ListEl(Math.random()*8)); // Параметр просто инициализирует значение param:Number
}
for( ; i < 3000 ; i++)
{
        valVect.push(null);
}
 
time = getTimer();
 
valVect.sort(function(a:ListEl,b:ListEl)
{
        if(a == null)
        {
                return -1;
        }
        else if(b == null)
        {
                return 1;
        }
        else
        {                                                       
        return (a.param == b.param) ? 0 : ((a.param > b.param) ? 1 : -1);                                                               
        }
});
 
trace(getTimer() - time);

Этот код работает тем дольше, чем больше null-элементов в векторе. Думал, это связанно с особенностями quick sort, он, кажется, плохо работает с уже сортированными структурами данных, но нет. Заменял null на конструкторы с единицами - всё становилось хорошо, работало моментально.

При всех null - 800 мс против 2 мс при полном отсутствии null в векторе.

P.S.: Ещё, раз уж зайдёт речь про вектора, задам несколько глупых вопросов.

1. Какая польза от использования свойства fixed = true? Понимаю, по ходу прирост скорости, но за счёт чего, что при этом происходит в самом векторе?

2. Можно ли реализовать вообще фиксированный вектор, чтобы обращение по индексу к элементам шло не итератором или ещё чёртичем для списка, а по смещению?

maxkar 18.05.2011 14:05

Тормоза кода связаны с тем, что ваш компаратор генерирует полную фигню на выходе. От него вообще-то ожидается, что если a < b, то b > a. А у вас если a == null и b == null указанное не выполняется. Поэтому можно даже и корректности сортировки не получить.

1. В первую очередь из-за того, что его размер не меняется, экономятся перераспределения памяти. Вполне может быть, что просто отсутствие изменения размера массива (с fixed == false) по быстродействию окажется таким же, что и при fixed == true.

2. А почему вы решили, что обращение идет итератором или по списку? Вектор то (в отличие от массива) плотная (dense) структура, на ней эффективно реализуется индексный доступ. В том числе и для resizeable vector, с амортизированной сложностью добавления и удаления в конец списка O(1).

semenyakinVS 18.05.2011 14:41

Ничего подобного. Компаратор правильно написан. Я проверил.
Единственное - он сортирует null-элементы в начало вектора, но это не влияет на время выполнения (это я тоже проверил).

Добавлено через 3 минуты
За ответы на вопросы спасибо.

maxkar 18.05.2011 14:51

Как же правильно то? Он почему-то считает, что null < null вместо того, что null == null. Компаратор не сортирует. Он сравнивает. И компаратор, игнорирующий при одном из сценариев выполнения второе значение правильным быть не может.

alatar 18.05.2011 16:39

Код AS3:

valVect.sort(function(a:Object,b:Object):int
{
    if(!a)
    {
        return -1;
    }
    else if(!b)
    {
        return 1;
    }
    else
    {                                                       
        return (a.param == b.param) ? 0 : ((a.param > b.param) ? 1 : -1);                                                               
    }
});

~1400-1850 ms
Код AS3:

valVect.sort(function(a:Object,b:Object):int
{
    if (!a && !b)
    {
        return 0;
    }
    else if(!a)
    {
        return -1;
    }
    else if(!b)
    {
        return 1;
    }
    else
    {                                                       
        return (a.param == b.param) ? 0 : ((a.param > b.param) ? 1 : -1);                                                               
    }
});

~50-200 ms
И это в дебаг версии.

semenyakinVS 18.05.2011 16:54

Аааа!.. Да, всё! Понял!
Был не прав. Тему можно закрывать.

P.S.:
Цитата:

if (!a && !b)
Круто! Не знал, что в AS так можно.

i.o. 18.05.2011 17:39

а если функцию сделать не анонимной, да еще и тип ей задать, то еще быстрее станет)

gloomyBrain 18.05.2011 18:16

Цитата:

а если функцию сделать не анонимной, да еще и тип ей задать, то еще быстрее станет
А если еще и !(a && b) написать, так оно вообще взлетит =)


Часовой пояс GMT +4, время: 22:28.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.