2010-12-03 3 views
1

Как указано в answer в моем question, я буду использовать векторы, чтобы изменить размер до N, читать и писать n-й элемент, где n < N. Если n слишком близко к N, тогда я создам другой вектор размера N + M и скопировать все элементы из 1-го вектора в 2-й и удалить 1-й. Так что, если я занимаюсь управлением памятью, и нет вставки и удаления, существуют ли преимущества использования вектора вместо массива, особенно для этого случая?stl vector vs array

P.S. Изменение размера и блокировка копирования потребуются редко.

EDIT: Как требовал Дэвид Родригес - dribeas, это программа технического анализа. Исторические цены на акции сохраняются как полосы OHLC в векторах. Поэтому мне действительно нужно хранить элементы в векторах. Также есть некоторые другие классы вычислений, называемые индикаторами, выполняются расчеты, основанные на ценах акций. Когда новая цена поступает через tcp, сначала акции обновляют свои бары и сразу же называет все связанные с ними индикаторы «вычисляют методы», говоря: «Хорошо, ребята, мой n-й бар был обновлен в это время. Все операции основаны на задачах, то есть запас никогда не обновляется до окончания последнего обновления, и аналогичным образом индикатор никогда не выполняет вычисления, пока последний продолжается. Одна задача за раз. И если новые обновления продолжаются слишком быстро, их можно кэшировать как задачи. Таким образом, акции могут дождаться завершения последнего обновления, и индикатор может аналогичным образом сохранить свои задачи, пока он был рассчитан, но запас не должен ждать, пока его индикаторы закончат свою работу. Здесь начинается проблема. Если приходит обновление, то запасы сначала выглядят его размер вектора штриха и проверяют, нужно ли его изменять. При необходимости он изменяет размеры своих векторов, хотя могут быть некоторые индикаторы, все еще работающие до предыдущего обновления. Индикатор может достигать своих данных о запасах, поскольку данные могут быть изменены. До сих пор у меня нет никаких проблем, потому что подсчеты индикаторов выполнялись очень быстро. Но я обеспокоен. В качестве решения акции могут генерировать второй более крупный вектор-бар и сообщать своим индикаторам, что они могут достигнуть второго вектора для предстоящих вычислений. В конце концов, через пару секунд весь доступ к первому вектору гибнет, и он может быть удален ужасно.

+0

Как я объяснил в комментариях к моему ответу, вы не можете вставлять элементы в вектор из одного потока и читать элементы из одного и того же вектора в другом потоке. Векторное перераспределение - это не единственная проблема; внутренняя бухгалтерская отчетность, выполняемая вектором, также является проблемой, и вы не можете делать какие-либо предположения о том, что это значит. После того, как вы предоставите доступ к вектору к потребительским потокам, вы не сможете изменить его снова, если только (a) вы не синхронизируете доступ к нему, что вы сказали, что не хотите делать, или (б) вы получаете всех потребителей прекратить доступ к вектору, что, вероятно, сложно. – 2010-12-04 01:01:56

+0

Для оптимальной производительности в многопоточной среде вы можете захотеть реализовать свой собственный контейнер. – 2010-12-04 01:03:46

+0

@ Джеймс Макнеллис: Что вы подразумеваете под внутренней бухгалтерией? – 2010-12-04 01:04:20

ответ

2

Похоже, что структура, которую вы действительно хотите, это std::deque, которая может быть добавлена ​​в амуртовое постоянное время.

На самом деле стратегия изменения размера - это то, что уже используется std::vector. Фактически используемая точная стратегия означает, что эта операция по существу равна O (1), но только в терминах многих приложений в течение длительного периода времени. Во всяком случае, похоже, нет никакой причины изобретать колесо на этом. просто использовать std::vector.push_back() или std::queue.push_back()

1
  1. Почему вы просто не изменить размер существующего вектора?
  2. Если вы не можете изменить существующий вектор, то вы можете использовать массив для этого я не вижу никаких плюсов для использования std:vector в этом случае для копирования вы можете использовать memcopy
  3. Вы можете использовать массив и размер ее realloc ,
0

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

По конкретному вопросу, если нет веских причин не делать этого, я всегда буду искать std::vector по массиву, если только по той причине, что многие операции уже реализованы, и вам не нужны для ручного управления памятью.

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

0

Я бы сказал, что в вашем случае, в худшем случае, вектор будет не лучше, чем динамически распределенный необработанный массив. Наверное, это будет более удобно.

Что касается вашей дилеммы, это звучит как нечто более легкое с неявным управлением памятью. Вы можете хранить входящие данные в общих указателях. Затем индикаторы захватывают общий указатель на нужные им данные, когда они начинают вычислять. Если появятся новые данные, которые потребуют недействительности старых данных, просто замените общий указатель на запас, содержащий старые данные, общим указателем, содержащим новые данные. Любой индикатор, все еще использующий старые данные, может продолжать использовать его, поскольку он по-прежнему имеет общий указатель на старые данные (предотвращение очистки старых данных), а старые данные будут очищены, когда все индикаторы, использующие данные, будут завершены и сбросьте общие указатели.