Эффективно заполните std :: vector: push_back vs operator [] [duplicate]

Вы хотите это:

class a:
    def __init__(self):
        self.list = []

Объявление переменных внутри объявления класса делает их членами класса, а не членами экземпляра. Объявление их внутри метода __init__ гарантирует, что новый экземпляр членов создается рядом с каждым новым экземпляром объекта, что является поведением, которое вы ищете.

8
задан jpo38 25 August 2015 в 09:10
поделиться

4 ответа

Лучшая производительность будет достигнута при избегании динамического перераспределения, поэтому постарайтесь, чтобы векторная память была достаточно большой, чтобы получать все элементы.

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

Как прокомментировал Мелкон, reserve еще лучше:

void myfnc_1(void *a_src, uint32_t a_segment) {
    size_t nSize = GetSize();
    std::vector<std::string> values;
    values.reserve( nSize );
    char* v = a_src;

    for (size_t i = 0; i < nSize; ++i) {
        values.push_back( std::string( v, a_segment ) );
        v += a_segment;
    }
}
4
ответ дан jpo38 26 August 2018 в 05:12
поделиться

Просто делайте то, что легче читать и поддерживать. Довольно часто это самое быстрое решение.

И даже если это не самый быстрый, кого это волнует? Возможно, ваше приложение будет на 1% медленнее.

-2
ответ дан Aaron McDaid 26 August 2018 в 05:12
поделиться
9
ответ дан Andrew 26 August 2018 в 05:12
поделиться

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

push_back требует дополнительных перераспределений при каждом превышении пропускной способности. Таким образом, вариант 2 может быть улучшен путем резервирования достаточно места, чтобы избежать перераспределения. Кроме того, более эффективно напрямую нажимать строку, чем пустить пустой, а затем переназначать. И есть конструктор для std::string, который очень удобен для ваших нужд: из последовательности (5) string (const char* s, size_t n);

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

Это код с использованием этих улучшений:

void myfnc_1(void *a_src, uint32_t a_segment)
{
    std::vector<std::string> values;
    size_t nSize = GetSize( );
    values.reserve(nSize);
    char* v = static_cast<char*> ( a_src );

    for (size_t i = 0; i < nSize; ++i)
    {
        values.push_back( std::string( v, a_segment) );
        v += a_segment;
    }
}
3
ответ дан Toby Speight 26 August 2018 в 05:12
поделиться
Другие вопросы по тегам:

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