Что является самым эффективным способом добавить один станд.:: вектор до конца другого?

Позвольте v1 быть целевым вектором, v2 должен быть добавлен к задней части его.

Я теперь делаю:

v1.reserve(v1.size() + v2.size()); 
copy(v2.begin(), v2.end(), back_inserter(v1));

Действительно ли это - самый эффективный путь? Или это может, возможно, быть сделано только через копирование блока памяти? Спасибо!

50
задан Alex Jenter 5 February 2010 в 05:59
поделиться

4 ответа

Мне кажется, что если у вас действительно есть pty (если вы не имеете в виду что-то другое под псевдотерминалом), то все, что вам нужно сделать, это отправить Control-C в этот FD. В качестве доказательства этого, я представляю следующий код в Python (но довольно близко к C требуется сделать это):

import pty, os, sys, time

pid, fd = pty.fork()
if pid == 0:
   os.execv('/bin/sh', ['/bin/sh', '-c',
         'while true; do date; sleep 1; done'])
   sys.exit(0)
time.sleep(3)
os.write(fd, '^C')
print 'results:', os.read(fd, 1024)

Это развивает процесс под pty, который запускает бесконечный цикл печати дата. Затем родитель ожидает 3 секунды и посылает управляющий сигнал C.

Это приводит к следующим выводам:

guin:/tmp$ time python /tmp/foo
results: Fri Feb  5 08:28:09 MST 2010
Fri Feb  5 08:28:10 MST 2010
Fri Feb  5 08:28:11 MST 2010

python /tmp/foo  0.02s user 0.01s system 1% cpu 3.042 total
guin:/tmp$

Он работал чуть более 3 секунд, распечатал дату 3 раза и вышел.

-121--3186079-

Как насчет:

defaultPort = (new Random()).Next(48620, 49150);
-121--981921-

После многих споров (и разумного комментария Маттье М. и виллинтехаспама) я изменю свое предложение на

v1.insert( v1.end(), v2.begin(), v2.end() );

Я сохраню прежнее предложение здесь:

v1.reserve( v1.size() + v2.size() ); 
v1.insert( v1.end(), v2.begin(), v2.end() );

Есть некоторые причины сделать это последним способом, хотя ни один из них не является достаточно сильным:

  • нет никакой гарантии относительно того, какой размер будет перераспределен вектору - например, если размер суммы равен 1025, он может быть перераспределен до 2048 - в зависимости от реализации. Такой гарантии для резерва тоже нет, но для конкретного осуществления это может быть правдой. Если охота на узкое место может быть разумным проверить это.
  • reserve заявляет, что наши намерения ясны - оптимизация может быть более эффективной в этом случае (резерв может подготовить кэш в некоторой первоклассной реализации).
  • также, с резервом у нас есть стандартная гарантия C++, что будет только одно перераспределение, в то время как вставка может быть реализована неэффективно и сделать несколько перераспределений (также что-то проверить с конкретной реализацией).
63
ответ дан 7 November 2019 в 10:44
поделиться

Вероятно, лучше и проще использовать специальный метод: vector.insert

v1.insert(v1.end(), v2.begin(), v2.end());

Как упоминает Майкл, если итераторы не являются итераторами ввода, вектор определит требуемый размер и скопирует добавленные данные за один раз с помощью линейного сложность.

22
ответ дан 7 November 2019 в 10:44
поделиться

Если вы используете Boost, вы можете загрузить разрабатываемую версию библиотеки RangeEx из Boost Vault . Эта библиотека lib. был принят в Boost некоторое время назад, но пока не интегрирован с основным дистрибутивом. В нем вы найдете новый алгоритм на основе диапазона, который делает именно то, что вы хотите:

boost::push_back(v1, v2);

Внутренне он работает как ответ, данный UncleBens, но код более краткий и читаемый.

7
ответ дан 7 November 2019 в 10:44
поделиться

Если у вас есть вектор типов пакетов и вам действительно нужна производительность, вы можете использовать memcpy, который должен быть быстрее, чем vector <>. Insert (...):

v2.resize(v1.size() + v2.size());
memcpy((void*)&v1.front(), (void*)&v2[v1.size()], sizeof(v1.front())*v1.size());

Обновление: {{1 }} Хотя я бы использовал это, только если производительность действительно, действительно , необходима, код безопасен для типов контейнеров.

3
ответ дан 7 November 2019 в 10:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: