я должен использовать алгоритм или код вручную в этом случае? - PullRequest
3 голосов
/ 05 апреля 2009

Хорошо, кто-нибудь, скажите мне, что было бы лучше. Мне нужно | = элементы одного вектора с другим. То есть я хочу

void orTogether(vector<char>& v1, const vector<char>& v2)
{
    typedef vector<char>::iterator iter;
    for (iter i = v1.begin(), iter j = v2.begin() ; i != v1.end(); ++i, ++j)
        *i |= *j;
}

Я не могу использовать for_each из-за необходимости обрабатывать 2 коллекции. Я полагаю, я мог бы сделать что-то вроде

struct BitWiseOr
{
    char operator()(const char& a, const char& b) {return a | b;}
};

void orTogether2(vector<char>& v1, const vector<char>& v2)
{
    transform(v1.begin(), v1.end(), v2.begin(), 
        v1.begin(), BitwiseOr());
}

Является ли это более эффективным решением, хотя верхнее уже на месте, а нижнее - это задание? Это прямо в середине цикла обработки, и мне нужен самый быстрый код из возможных.

Редактировать: Добавлен (очевидный?) Код для BitwiseOr. Кроме того, я получаю много комментариев о не связанных вещах, таких как проверка длины v2 и изменение имен. Это всего лишь пример, реальный код более сложный.

Ну, я профилировал оба. orTogether2 намного быстрее, чем orTwo, поэтому я буду использовать метод transform. Я был удивлен, orTogether2 был примерно в 4 раза быстрее в режиме выпуска MSVC9. Я запускал его дважды, меняя порядок во второй раз, чтобы убедиться, что это не какая-то проблема с кешем, а те же результаты. Спасибо всем за помощь.

Ответы [ 5 ]

12 голосов
/ 05 апреля 2009

Нижний компилируется так, чтобы эффективно совпадать с первым, ваш функтор ИЛИ обязательно будет встроен. Таким образом, вторая идиома более гибкая, если вам когда-либо понадобится добавить больше гибкости или отладочных фреймворков или чего-то еще.

Поскольку первое не принесет пользы, используйте метод transform. Войдя в эту привычку, вы перестанете даже рассматривать явный выбор цикла для всех ваших приложений, поскольку это не нужно. Преимущество только *1004* по сравнению с первым методом заключается в том, что его легче объяснить начинающим программистам на C ++, которым более комфортно работать с необработанным C.

5 голосов
/ 05 апреля 2009

Хватай свои часы и измеряй

2 голосов
/ 05 апреля 2009

На самом деле не из чего выбирать, пока мы не увидим, как реализован MyBitwiseOrObject. Почему бы вам не запустить несколько тестов?

Проблема с transform заключается в том, что вам нужно иметь отдельный функтор и определять его в области пространства имен (далеко от места его использования). Лямбда решает эту проблему - вы можете взглянуть на Boost Lambda Library.

1 голос
/ 06 апреля 2009

Алгоритмы, предоставляемые STL, можно считать равными

  1. правильный
  2. реализовано достаточно быстро
  3. имеют гарантию сложности исполнения (если указано в стандарте)

Поэтому вы не ошибетесь, используя их. Фактически, для некоторых проблем разработчики STL могут специально использовать более быстрые реализации на основе спецификации шаблона.

0 голосов
/ 05 апреля 2009

Вы предварительно оптимизируете? Вы знаете, что один быстрее другого? Я подозреваю, что они довольно похожи.

Тем не менее, я бы использовал преобразование. Пусть библиотека, которая хорошо проверена, выполняет тяжелую работу. Держите ваш код простым и чистым. Вы можете не знать точно, что происходит внутри каждого, но вы можете доверять дизайнерам библиотеки, которые сделали хорошую работу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...