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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> И снова про производительность std::vector 
:(
    Опции темы
xTr1m
Дата 8.5.2013, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



День добрый. Случайно играясь с производительностью, получил очень странный для меня результат. Функция двоичного поиска для вектора и "сырого" массива
Код

unsigned int BynarySearch(vector<int> &vec, int value)
{
    unsigned int start = 0, end = vec.size() - 1;
    while(true)
    {
        int tmpIndex = start + (end - start) / 2;
        if(vec[tmpIndex] == value)
            return tmpIndex;        

        if(value < vec[tmpIndex]) end = tmpIndex;
        else  start = tmpIndex;            

        if(end - start == 1)
        {
            if(vec[start] == value) return start;
            if(vec[end] == value) return end;
        }
    }

    return -1;
}

unsigned int BynarySearch(int *arr, const int size, int value)
{
    unsigned int start = 0, end = size - 1;
    while(true)
    {
        int tmpIndex = start + (end - start) / 2;
        if(arr[tmpIndex] == value)        
            return tmpIndex;        

        if(value < arr[tmpIndex]) end = tmpIndex;
        else  start = tmpIndex;            

        if(end - start == 1)
        {
            if(arr[start] == value) return start;
            if(arr[end] == value) return end;
        }
    }

    return -1;
}

То есть все одинаковое, кроме способа обращения к элементу (хотя и он по большому счету схож). Прогнав данные функции 1000000 раз по отсортированному массиву от 1 до 1000000 я получил, что вектор осилил это за 2,5 сек против 0,15 для "сырого" массива. Все это для дебага, но разница в 16 раз (обычный std::find вообще свыше 120 сек). Я конечно понимаю, что вектор функциональнее и уже готовое решение (с большей возможностью для расширения / изменения) и в конце концов стандарт, но какова цена? Может я не так меряю?
PM MAIL WWW ICQ   Вверх
Static
Дата 8.5.2013, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Попробуйте все-таки в релизе.
--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
bsa
Дата 8.5.2013, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



xTr1m, вообще-то, в STL есть уже двоичный поиск - upper_bound и lower_bound. Может стоит не изобретать велосипед?
Думаю, в релизе скорость работы сравняется.
PM   Вверх
xTr1m
Дата 8.5.2013, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



То, что поиск есть я знаю, это я уже так, для себя. Попробовал в релизе, действительно стало сравнимо. Но, что он там делает то? Вроде, строк типа 
Код

#ifdef __debug

я там не видел.

хотя все равно разница есть. Вектор = 0.18, Массив = 0. Но это уже для 2000000 прогонов.

Добавлено через 14 минут и 31 секунду
Все равно возникает ощущение, что те, кто придумывает свой велосипед иногда правы.

Это сообщение отредактировал(а) xTr1m - 8.5.2013, 16:40
PM MAIL WWW ICQ   Вверх
kamre
Дата 9.5.2013, 05:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(bsa @  8.5.2013,  16:24 Найти цитируемый пост)
Думаю, в релизе скорость работы сравняется.

У меня тоже в релизе вектор чуть отстает:
Код

#include <vector>
#include <iostream>
#include <chrono>

using namespace std;
using namespace chrono;

unsigned int BinarySearch(vector<int> &vec, int value)
{
    unsigned int start = 0, end = vec.size() - 1;
    while(true)
    {
        int tmpIndex = start + (end - start) / 2;
        if(vec[tmpIndex] == value)
            return tmpIndex;

        if(value < vec[tmpIndex]) end = tmpIndex;
        else  start = tmpIndex;

        if(end - start == 1)
        {
            if(vec[start] == value) return start;
            if(vec[end] == value) return end;
        }
    }

    return -1;
}

unsigned int BinarySearch(int *arr, const int size, int value)
{
    unsigned int start = 0, end = size - 1;
    while(true)
    {
        int tmpIndex = start + (end - start) / 2;
        if(arr[tmpIndex] == value)
            return tmpIndex;

        if(value < arr[tmpIndex]) end = tmpIndex;
        else  start = tmpIndex;

        if(end - start == 1)
        {
            if(arr[start] == value) return start;
            if(arr[end] == value) return end;
        }
    }

    return -1;
}

template <typename F>
void test(const char* desc, F f)
{
    cout << desc << ": ";
    const size_t n = 10;
    typedef high_resolution_clock::time_point tp;
    tp t0 = high_resolution_clock::now();
    for (size_t i = 0; i < n; ++i) {
        f();
    }
    tp t1 = high_resolution_clock::now();
    duration<double> time_span = duration_cast<duration<double>>(t1 - t0);
    cout << time_span.count()/n << " sec" << endl;
}

int main()
{
    const size_t sz = 2000000;
    vector<int> v;
    for (size_t i = 0; i < sz; ++i) {
        v.push_back(i);
    }
    auto vect = [&] () -> int {
        unsigned int res;
        for (size_t i = 0; i < sz; ++i) {
            res = BinarySearch(v, i);
        }
        return res;
    };
    auto array = [&] () -> int {
        unsigned int res;
        for (size_t i = 0; i < sz; ++i) {
            res = BinarySearch(v.data(), sz, i);
        }
        return res;
    };
    test("vector", vect);
    test("array", array);
}

сборка так: g++ -std=c++11 -O3 binary_search_perfo.cpp
выводит:
vector: 0.462927 sec
array: 0.401723 sec
причем чиселки стабильные, пара цифр после запятой не меняется вообще
PM MAIL   Вверх
Static
Дата 9.5.2013, 10:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Вектор может еще отставать из-за проверки на выход за пределы массива.
--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
kamre
Дата 9.5.2013, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Static @  9.5.2013,  10:19 Найти цитируемый пост)
Вектор может еще отставать из-за проверки на выход за пределы массива.

А где здесь проверка на выход за границы:

Код

const_reference
operator[](size_type __n) const
{ return *(this->_M_impl._M_start + __n); }

?
 По идее при вызове этого оператора всегда есть лишняя косвенность, но оптимизатор должен обнаружить общее выражение "this->_M_impl._M_start", значение которого не меняется внутри функции,  и не перевычислять каждый раз.
PM MAIL   Вверх
Static
Дата 9.5.2013, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(kamre @  9.5.2013,  09:34 Найти цитируемый пост)
А где здесь проверка на выход за границы:

Не знаю smile Перед своим предыдущим комментарием специально погуглил, пишут, что в студии, например, эта проверка даже в релизе включена.
--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
volatile
Дата 9.5.2013, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(xTr1m @  8.5.2013,  16:01 Найти цитируемый пост)
Все это для дебага, но разница в 16 раз 

Никогда не нужно измерять скорость приплюснутого кода в дебаге. Никогда!
При включенной оптимизации, разница будет составлять проценты.
Массив быстрей будет, по любому, но не значительно.

Цитата(kamre @  9.5.2013,  05:53 Найти цитируемый пост)
vector: 0.462927 sec
array: 0.401723 sec

да, вот это похоже на реальные цифры

PM MAIL   Вверх
kamre
Дата 9.5.2013, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(volatile @  9.5.2013,  13:24 Найти цитируемый пост)
Массив быстрей будет, по любому, но не значительно.

А чем это "по любому" объясняется?
PM MAIL   Вверх
volatile
Дата 9.5.2013, 14:56 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(kamre @  9.5.2013,  14:10 Найти цитируемый пост)
А чем это "по любому" объясняется? 

ну например, псевдокод
vector [2] = 3;
это будет скомпилировано как-то так ==>

int * p = vector.pointer; 
p[2] = 3;

Вектор, это структура, и чтобы взять указатель, нужно одно лишнее действие.
Хотя в идеале, конечно, оптимизатор должен и это соптимизировать, 
Не исключаю реализаций, где разница будет сведена к нулю. по крайней мере для таких простых выражений.
В общем же случае, вектор всегда будет чуток помедленее.
Небольшая плата, за большое удобство.

PM MAIL   Вверх
VSB
Дата 19.5.2013, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



В студии есть дополнительные проверки, по умолчанию включенные в дебаге, чтобы проще отлаживать было. Подробнее - http://msdn.microsoft.com/en-us/library/aa985872.aspx
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0562 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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