Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> find_if, засчет чего такая скорость? 
:(
    Опции темы
xTr1m
Дата 26.2.2010, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 692
Регистрация: 9.2.2005
Где: Москва

Репутация: 1
Всего: 1



Доброго времени суток. Решил я посмотреть есть ли причины использовать std::find_if (за одну такую фразу, думаю, многие меня побьют =))
Сделал тестовый пример. Положил в vector 10000 строк "test" и сделал два варианта поиска:
find_if
Код

struct Functor
{
    bool operator() (const string &str)
    {
        int index = str.find("lol");
        return false;
    }
};
...
for(int y=0; y<m_count; ++y)
     find_if(items.begin(), items.end(), Functor());


поиск перебором
Код

for(int y=0; y<m_count; ++y)
{
    vector<string>::iterator Iter;
    for(Iter=items.begin(); Iter!=items.end(); ++Iter)
    {        
        if(-1 != (*Iter).find("lol"))
            break;
    }        
}

при m_count = 1000, find_if отработал за 4 секунды, а поиск перебором аж за 10. за счет чего так получается? Может я конечно многого не знаю, но я считал, что find_if также должен пройтись по всем элементам массива + ведь еще "тратится время" на вызов функтора. а в результате имеем, что быстрее. В чем причина?
PM MAIL WWW ICQ   Вверх
Alca
Дата 26.2.2010, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 7
Всего: 50



Можно глянуть исходники STL


--------------------
PM WWW ICQ Skype Jabber   Вверх
andrew_121
Дата 26.2.2010, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



Цитата(xTr1m @  26.2.2010,  13:17 Найти цитируемый пост)
за счет чего так получается?

потому как std::find_if() не ищет тупым перебором.
а вообще, STL не зря так назвали! и не идиоты пишут стандартные алгоритмы!


Это сообщение отредактировал(а) andrew_121 - 26.2.2010, 14:11


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Ozerich
Дата 26.2.2010, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 164
Регистрация: 2.8.2009
Где: Минск, Беларусь

Репутация: нет
Всего: 5



Цитата(andrew_121 @ 26.2.2010,  12:48)
Цитата(xTr1m @  26.2.2010,  13:17 Найти цитируемый пост)
за счет чего так получается?

потому как std::find_if() не ищет тупым перебором.
а вообще, STL не зря так назвали! и не идиоты пишут стандартные алгоритмы!

А разве возможно искать что то не в отсортированном массиве, не используя перебор? smile 
--------------------
C++(STL) / DHTML(CSS) / Javascript / PHP  Developer
PM MAIL ICQ Skype   Вверх
xTr1m
Дата 26.2.2010, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 692
Регистрация: 9.2.2005
Где: Москва

Репутация: 1
Всего: 1



Вот я прошу хотя бы намекнуть, как можно организовать поиск в неупорядоченном массиве без прохождения его всего. А в моем случае поиск как раз проходит по всем элементам, так как я ищу элемент, которого там нет.
PM MAIL WWW ICQ   Вверх
chaos
Дата 26.2.2010, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Серийный программист
****


Профиль
Группа: Завсегдатай
Сообщений: 2979
Регистрация: 7.7.2004
Где: Екатеринбург

Репутация: 6
Всего: 44



xTr1m, а почему ты решил что узкое место именно перебор? может тормоз сравнение?!

Добавлено через 1 минуту и 17 секунд
ЗЫ какова смысловая нагрузка "for(int y=0; y<m_count; ++y)" ?
PM WWW   Вверх
xTr1m
Дата 26.2.2010, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 692
Регистрация: 9.2.2005
Где: Москва

Репутация: 1
Всего: 1



Смысловая нагрузка
Цитата

for(int y=0; y<m_count; ++y)

просто, чтобы время увеличить кол-во поисков, чтобы время выполнения измерялось секундами. 

А сравнение то везде одинаково. собственно бог с ним, со сравнением. меня интересует, что же такое происходит во время find_if, может он просто не по всем элементам проходит =)))
Чего исходник пока найти не могу
PM MAIL WWW ICQ   Вверх
Ozerich
Дата 26.2.2010, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 164
Регистрация: 2.8.2009
Где: Минск, Беларусь

Репутация: нет
Всего: 5



Искать в неотсортированном массиве быстрее чем за линейное время не возможно. Используя бинарный поиск мы за log N(N - длина массива) можем найти элемент но массив должен быть отсортирован.
--------------------
C++(STL) / DHTML(CSS) / Javascript / PHP  Developer
PM MAIL ICQ Skype   Вверх
andrew_121
Дата 26.2.2010, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



Цитата(Ozerich @  26.2.2010,  13:51 Найти цитируемый пост)
А разве возможно искать что то не в отсортированном массиве, не используя перебор?

я ставил акцент на слово - тупым.

вот код из STL поставляемой с gcc-4.5.0
Код

template<typename _RandomAccessIterator, typename _Predicate>
  _RandomAccessIterator
  __find_if(_RandomAccessIterator __first, _RandomAccessIterator __last,
         _Predicate __pred, random_access_iterator_tag)
{
    typename iterator_traits<_RandomAccessIterator>::difference_type
        __trip_count = (__last - __first) >> 2;

    for (; __trip_count > 0; --__trip_count) {
        if (__pred(*__first))
            return __first;
        ++__first;
    
        if (__pred(*__first))
            return __first;
        ++__first;
    
        if (__pred(*__first))
            return __first;
        ++__first;
    
        if (__pred(*__first))
            return __first;
        ++__first;
    }

    switch (__last - __first) {
        case 3:
            if (__pred(*__first))
                return __first;
            ++__first;
        case 2:
            if (__pred(*__first))
                return __first;
            ++__first;
        case 1:
            if (__pred(*__first))
                return __first;
            ++__first;
        case 0:
        default:
            return __last;
    }
}

хороша оптимизация? smile 


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
xTr1m
Дата 26.2.2010, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 692
Регистрация: 9.2.2005
Где: Москва

Репутация: 1
Всего: 1



О, спасибо. С ходу не осилил, приду домой - буду курить.
PM MAIL WWW ICQ   Вверх
Shaggie
Дата 26.2.2010, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 570
Регистрация: 21.12.2006
Где: outer space

Репутация: нет
Всего: 72



Прибавь к этому ещё два небольших момента.

Цитата(xTr1m @  26.2.2010,  13:17 Найти цитируемый пост)
for(Iter=items.begin(); Iter!=items.end(); ++Iter)

У тебя в цикле end() вычисляется каждый раз заново (даже если это всего лишь разница между указателями), а в find_if() приезжает уже готовое значение.

Цитата(xTr1m @  26.2.2010,  13:17 Найти цитируемый пост)
+ ведь еще "тратится время" на вызов функтора

Код функтора встраивается и оверхеда на его вызов нет.

Цитата(xTr1m @  26.2.2010,  14:11 Найти цитируемый пост)
О, спасибо. С ходу не осилил

Цикл сам по себе штука медленная, поэтому для оптимизации их разворачивают. Где-то это делает умный компилятор, где-то разработчики time critical библиотек общего назначения (как в данном случае), в отдельных грустных случаях разворачивать цикл приходится самому программисту.
В данном случае на один шаг цикла происходит четыре операции сравнения.


--------------------
Цитата(alina3000 @  6.3.2014,  10:47 Найти цитируемый пост)
Сорри что не по теме 
PM MAIL ICQ GTalk Jabber   Вверх
xvr
Дата 26.2.2010, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(xTr1m @ 26.2.2010,  13:17)
Код

struct Functor
{
    bool operator() (const string &str)
    {
        int index = str.find("lol");
        return false;
    }
};
...
for(int y=0; y<m_count; ++y)
     find_if(items.begin(), items.end(), Functor());

при m_count = 1000, find_if отработал за 4 секунды, а поиск перебором аж за 10. за счет чего так получается?

Может за счет того, что твой Functor всегда возвращает false? Компилятор вообще имеет право вообще удалить вызов и find_if и охватывающего цикла

PM MAIL   Вверх
xTr1m
Дата 26.2.2010, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 692
Регистрация: 9.2.2005
Где: Москва

Репутация: 1
Всего: 1



xvr,  надеюсь он так не самовольничает =)
PM MAIL WWW ICQ   Вверх
Леопольд
Дата 26.2.2010, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(xTr1m @  26.2.2010,  15:07 Найти цитируемый пост)
xvr,  надеюсь он так не самовольничает =) 

Почему-то мне кажется что время замерялось на дебаг версии. Попробуй замерить на релизах... smile

Это сообщение отредактировал(а) Леопольд - 26.2.2010, 18:29


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
xvr
Дата 26.2.2010, 19:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(xTr1m @ 26.2.2010,  15:07)
xvr,  надеюсь он так не самовольничает =)

Почему бы нет - все функции inline, не имеют побочных эффектов, функтор константа. Вполне может все свернуть.
Вот если привести функтор в соотвествие с тем, что было написано для 2й версии, тогда можно сравнивать

PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0902 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.