Глядя на выходные данные сборки, gcc фактически развертывает этот цикл, используя регистры mmx для выгрузки 16 байтов за раз, пока он не приблизится к концу. Я бы сказал, что это довольно быстро. Версия memset переходит на memset, что, я думаю, примерно так же быстро. Я бы использовал ваш метод.
Всезнающий
Но переход к memset - это отдельная инструкция, поэтому ее использование приведет к уменьшению двоичного размера.
Александр Шишенко
2
это не совсем то, о чем просил OP, но просто переназначение вашего вектора на новый с таким же размером ( v = std::vector<int>(vec_size,0)) кажется немного быстрее, чем fillна моей машине
Yibo Yang
1
Это самый идиоматический способ сделать это, более идиоматический, чем использование assign.
AlfC
1
назначает ли это новому вектору распределение кучи? а затем отменить выделение существующего вектора? Я мог видеть, что это медленнее, чем memset и др.
Конрад Джонс
150
Как всегда, когда вы спрашиваете о самом быстром: Мера! Используя Методы выше (на Mac, используя Clang):
используя 100000 итераций для вектора 10000 целых.
Изменить: Если изменение этих чисел правдоподобно меняет результирующее время, вы можете иметь некоторую уверенность (не так хорошо, как проверка кода окончательной сборки), что искусственный тест не был полностью оптимизирован. Конечно, лучше всего испортить представление в реальных условиях.
конец Править
+1. Этот конкретный тест не является окончательным, но суть абсолютно правильная, вы должны написать тест производительности альтернатив, поскольку они будут фактически использоваться. Если нет разницы в производительности, используйте тот, который является самым простым источником.
Стив Джессоп
3
«... не окончательно ...» IMO, эта неубедительность сама по себе уже является хорошей точкой для проведения тестов, чаще всего Оптимизатор уже делает очень хорошую работу для ситуаций, о которых спрашивал ОП. И я бы изменил ваше последнее предложение следующим образом: «Если нет существенной разницы в производительности ...»
Кроме того, ничего себе, если вы заботитесь о скорости без оптимизации (что может быть правдоподобно, если вы развертываете в режиме «отладки», что делают некоторые команды), fillвыглядит ужасно. В этом тесте он на два порядка медленнее.
Кайл Стрэнд,
5
@KyleStrand: Дело не в том, что заливка ужасна, это шаблон, и код генерируется с -O0 внутри вашего модуля перевода. Когда вы используете memset, вы используете код libc, который был скомпилирован с -O3 (даже когда вы компилируете свой код с -O0). Если вы заботитесь о скорости отладки и используете шаблоны, вам придется использовать явную реализацию шаблона в отдельном файле, который вы компилируете с -O3
Поскольку стандарт (TC1 2003) гарантирует, что std :: vector является непрерывным в памяти, это должно быть хорошо. Если ваша библиотека c ++ не соответствует TC1 2003, не используйте это.
Марио
2
@Mario: я бы не опубликовал это, если бы это не было правдой и, конечно, предполагалось, что это хорошо известно. :) Но спасибо.
расслабиться
1
Я проверил сборку. ::std::fillМетод расширяется к чему - то , что это чертовски быстро, хотя и немного по кодовым bloaty стороне , так как это все инлайн. Я все еще использовал бы это, хотя, потому что это намного лучше читать.
Всезнающий
4
Лучше добавить проверку, если вектор пуст, и ничего не делать в этом случае. Вычисление & buf [0] для пустого вектора может генерировать утверждения в коде STL.
Сергей
4
пытаться
std::fill
а также
std::size siz = vec.size();//no memory allocating
vec.resize(0);
vec.resize(siz,0);
У меня был тот же вопрос, но относительно довольно короткий vector<bool>(на самом деле стандарт позволяет реализовать его внутренне иначе, чем просто непрерывный массив логических элементов). Поэтому я повторил слегка измененные тесты Фабио Фракасси. Результаты следующие (раз в секундах):
-O0 -O3
----------------
memset 0.6661.045
fill 19.3571.066iterator67.3681.043
assign 17.9750.530for i 22.6101.004
Так что, видимо, для этих размеров, vector<bool>::assign()это быстрее. Код, используемый для тестов:
Ответы:
источник
v = std::vector<int>(vec_size,0)
) кажется немного быстрее, чемfill
на моей машинеassign
.Как всегда, когда вы спрашиваете о самом быстром: Мера! Используя Методы выше (на Mac, используя Clang):
используя 100000 итераций для вектора 10000 целых.
Изменить: Если изменение этих чисел правдоподобно меняет результирующее время, вы можете иметь некоторую уверенность (не так хорошо, как проверка кода окончательной сборки), что искусственный тест не был полностью оптимизирован. Конечно, лучше всего испортить представление в реальных условиях. конец Править
для справки использованный код:
Вывод: пользуйтесь
std::fill
(потому что, как говорили другие, это идиоматично)!источник
assign
медленнее, за исключением небольших мощностей наlibc++
. CODE coliru / pastefill
выглядит ужасно. В этом тесте он на два порядка медленнее.Как насчет
assign
функции-члена?источник
Если это просто вектор целых чисел, я бы сначала попробовал:
Это не очень C ++, поэтому я уверен, что кто-то предоставит правильный способ сделать это. :)
источник
::std::fill
Метод расширяется к чему - то , что это чертовски быстро, хотя и немного по кодовым bloaty стороне , так как это все инлайн. Я все еще использовал бы это, хотя, потому что это намного лучше читать.пытаться
а также
источник
У меня был тот же вопрос, но относительно довольно короткий
vector<bool>
(на самом деле стандарт позволяет реализовать его внутренне иначе, чем просто непрерывный массив логических элементов). Поэтому я повторил слегка измененные тесты Фабио Фракасси. Результаты следующие (раз в секундах):Так что, видимо, для этих размеров,
vector<bool>::assign()
это быстрее. Код, используемый для тестов:Я использовал компилятор GCC 7.2.0 на Ubuntu 17.10. Командная строка для компиляции:
источник