Re: Заполняем vector<vector<string> >
От: Шахтер Интернет  
Дата: 12.08.09 14:20
Оценка: 1 (1) -2
Здравствуйте, igna, Вы писали:

I>Пример внизу заполняет vector<vector<string> > беря значения из некой коллекции:


I>Пример реализован прямолинейно, а как бы вы написали?


Я бы уволил с работы человека, использующего такие конструкции.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[7]: Заполняем vector<vector<string> >
От: IROV..  
Дата: 12.08.09 15:17
Оценка: 4 (1)
I>Прошу прощения, похоже я недостаточно точно выразился. Под конкретным примером имел в виду код, который можно скомпилировать, запустить и посмотреть, как компилятор не соптимизирует возврат по значению.


#    include <vector>
#    include <list>
#    include <string>

typedef std::list<std::string> TListFlags;
typedef std::vector<std::string> TVectorFlags;

static void s_converterListToVectorFlags( const TListFlags & _in, TVectorFlags & _out )
{
    for( TListFlags::const_iterator 
        it = _in.begin(),
        it_end = _in.end();
    it != it_end;
    ++it )
    {
        _out.push_back( *it );
    }
}

static TVectorFlags s_converterListToVectorFlags2( const TListFlags & _in )
{
    TVectorFlags out;

    for( TListFlags::const_iterator 
        it = _in.begin(),
        it_end = _in.end();
    it != it_end;
    ++it )
    {
        out.push_back( *it );
    }

    return out;
}


class Properties
{
public:
    void setFlags( const TListFlags & _list )
    {
        m_flags.clear();
        s_converterListToVectorFlags( _list, m_flags );

        //    m_flags = s_converterListToVectorFlags2( _list )
    }

protected:    
    TVectorFlags m_flags;
};

void main()
{
    Properties pr;

    TListFlags ff;
    ff.push_back( "const" );
    ff.push_back( "copy" );
    ff.push_back( "alpha" );

    pr.setFlags( ff );

    TListFlags gg;
    gg.push_back( "write" );
    gg.push_back( "read" );
    gg.push_back( "float" );

    pr.setFlags( gg );
}
я не волшебник, я только учусь!
Re: Заполняем vector<vector<string> >
От: zaufi Земля  
Дата: 12.08.09 12:01
Оценка: 1 (1)
Здравствуйте, igna, Вы писали:

I>Пример реализован прямолинейно, а как бы вы написали?

не знаю что такое Text в твоей проге, но если гдето там (в коде до указанного примера) есть буфер (char* или std::string например) с текстом над которым нужно произвести данные зверства...

0) я бы сначла нарезал его boost::algorithm::split'ом на предложения (например по символу '.' в тексте), результат получил бы в std::vector<boost::iterator_range<char*> > или std::vector<boost::iterator_range<std::string::const_iterator> > (не знаю в чем у тя хрянятся строки)

1) потом проходясь по вектору range'й резал бы по словам, опять таки split'ом в вектор range'й и полученые вектора складывал бы в вектор векторов буст итератор рэнджей от констных стринговых итераторов

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

в результате не буит никаких копирований строк вообще... ну и размер внешнего вектора тоже буит известен после шага 0
Re[2]: Заполняем vector<vector<string> >
От: SleepyDrago Украина  
Дата: 12.08.09 13:50
Оценка: 1 (1)
Здравствуйте, zaufi, Вы писали:

полностью с вами согласен — правда можно чуток поковырять детали

I>>Пример реализован прямолинейно, а как бы вы написали?

Z>не знаю что такое Text в твоей проге, но если гдето там (в коде до указанного примера) есть буфер (char* или std::string например) с текстом над которым нужно произвести данные зверства...

Z>0) я бы сначла нарезал его boost::algorithm::split'ом на предложения (например по символу '.' в тексте), результат получил бы в std::vector<boost::iterator_range<char*> > или std::vector<boost::iterator_range<std::string::const_iterator> > (не знаю в чем у тя хрянятся строки)


Если разделители фиксированного размера, то рулит хранение позиций начала предложений. Экономия памяти на 64х битной платформе в типовом случае в 4 раза (разумеется при известных ограничениях). Так что вы несомненно правы, а предлагается лишь небольшое влияние на константы алгоритма.

Z>1) потом проходясь по вектору range'й резал бы по словам, опять таки split'ом в вектор range'й и полученые вектора складывал бы в вектор векторов буст итератор рэнджей от констных стринговых итераторов

вектор векторов можно скипнуть совсем — достаточно 2 вектора : вектор слов + на каждое предложение индекс начала. Причем вектор наверное стоит заменить на что-то блочное (упражнения для читателя).

Z>не знаю уж зачем тебе такое надо... -- не иначе словарь составляешь для брутфорсового подбора паролей

Он известный ценитель этого форума так что код скорее всего измеряет чью-то скорость.

Z>в результате не будет никаких копирований строк вообще... ну и размер внешнего вектора тоже буит известен после шага 0

В общем то все верно для generic case. Но на практике часто можно воспользоваться тем, что данные ограничены по длине.
Заполняем vector<vector<string> >
От: igna Россия  
Дата: 12.08.09 05:52
Оценка:
Пример внизу заполняет vector<vector<string> > беря значения из некой коллекции:

vector<vector<string> > text_to_vvs(Text const* const text)
{
    vector<vector<string> > vvs;
    for (Sentence const* sent = text->FirstSentence(); sent; sent = sent->Next()) {
        vector<string> vs;
        for (Word const* w = sent->FirstWord(); w; w = w->Next())
            vs.push_back(w->Str()); // w->Str() returns char const*
        vvs.push_back(vs);
    }
    return vvs;
}


Пример реализован прямолинейно, а как бы вы написали?
Re: Заполняем vector<vector<string> >
От: Alexander G Украина  
Дата: 12.08.09 06:03
Оценка:
Здравствуйте, igna, Вы писали:

I>Пример внизу заполняет vector<vector<string> > беря значения из некой коллекции:


I>Пример реализован прямолинейно, а как бы вы написали?


Можно сэкономить на одном из копирований.

vector<vector<string> > text_to_vvs(Text const* const text)
{
    vector<vector<string> > vvs;
    for (Sentence const* sent = text->FirstSentence(); sent; sent = sent->Next()) {
        vvs.push_back(vector<string>());
        vector<string> & vs = vvs.back();
        for (Word const* w = sent->FirstWord(); w; w = w->Next())
            vs.push_back(w->Str()); // w->Str() returns char const*
    }
    return vvs;
}


Можно определить размер и зарезервить, сэкономить на других копированиях.
Русский военный корабль идёт ко дну!
Re: Заполняем vector<vector<string> >
От: Аноним  
Дата: 12.08.09 06:44
Оценка:
Здравствуйте, igna, Вы писали:

I>Пример внизу заполняет vector<vector<string> > беря значения из некой коллекции:


I>
I>vector<vector<string> > text_to_vvs(Text const* const text)
I>{
I>    vector<vector<string> > vvs;
I>    for (Sentence const* sent = text->FirstSentence(); sent; sent = sent->Next()) {
I>        vector<string> vs;
I>        for (Word const* w = sent->FirstWord(); w; w = w->Next())
I>            vs.push_back(w->Str()); // w->Str() returns char const*
I>        vvs.push_back(vs);
I>    }
I>    return vvs;
I>}
I>


I>Пример реализован прямолинейно, а как бы вы написали?



I>
I>size_t sentence_to_vs(vector<string>& vs,Sentence const* sent)
I>{
I>    size_t count=0;
I>    for (Word const* w = sent->FirstWord(); w; w = w->Next(),count++)
I>       vs.push_back(w->Str()); // w->Str() returns char const*
I>    return count;
I>}


I>size_t text_to_vvs(vector<vector<string> >& vvs,Text const* const text)
I>{
I>    
I>    size_t count=0;
I>    for (Sentence const* sent = text->FirstSentence(); sent; sent = sent->Next()) {
I>        vector<string>& vs = *vvs.insert(vvs.end(),vector<string>()); 
I>        count+=sentence_to_vs(vs,sent);
I>    }
I>    return count;
I>}
I>
Re: Заполняем vector<vector<string> >
От: _Dreamer Россия  
Дата: 12.08.09 06:48
Оценка:
Здравствуйте, igna, Вы писали:

I>Пример внизу заполняет vector<vector<string> > беря значения из некой коллекции:

I>Пример реализован прямолинейно, а как бы вы написали?

а NRVO в Вашем компиляторе есть ? оно здесь срабатывает ?
а то я бы написал влоб —
void text_to_vvs(Text const* const text, vector< vector< string > >& result);

// или 
vector< vector< string > >& text_to_vvs(Text const* const text, vector< vector< string > >& result);
Re: Заполняем vector<vector<string> >
От: Юрий Жмеренецкий ICQ 380412032
Дата: 12.08.09 07:00
Оценка:
Здравствуйте, igna, Вы писали:

I>Пример внизу заполняет vector<vector<string> > беря значения из некой коллекции:


I>
I>vector<vector<string> > text_to_vvs(Text const* const text)
I>{
I>    vector<vector<string> > vvs;
I>    for (Sentence const* sent = text->FirstSentence(); sent; sent = sent->Next()) {
I>        vector<string> vs;
I>        for (Word const* w = sent->FirstWord(); w; w = w->Next())
I>            vs.push_back(w->Str()); // w->Str() returns char const*
I>        vvs.push_back(vs);
I>    }
I>    return vvs;
I>}
I>


I>Пример реализован прямолинейно, а как бы вы написали?


Скорее всего без возврата по значению.
Re: Заполняем vector<vector<string> >
От: sokel Россия  
Дата: 12.08.09 07:45
Оценка:
Здравствуйте, igna, Вы писали:

I>Пример реализован прямолинейно, а как бы вы написали?


При добавлении очередного предложения произойдет реаллокация вектора и все ранее добавленные будут копироваться. По значению. Возможно, лучше будет не vector<vector>, a vector<vector*>.
Re[2]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 12.08.09 07:57
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Можно сэкономить на одном из копирований.


AG>vector<vector<string> > text_to_vvs(Text const* const text)
AG>{
AG>    vector<vector<string> > vvs;
AG>    for (Sentence const* sent = text->FirstSentence(); sent; sent = sent->Next()) {
AG>        vvs.push_back(vector<string>());
AG>        vector<string> & vs = vvs.back();
AG>        for (Word const* w = sent->FirstWord(); w; w = w->Next())
AG>            vs.push_back(w->Str()); // w->Str() returns char const*
AG>    }
AG>    return vvs;
AG>}


Ты так пишешь всегда или только тогда, когда нужно cоптимизировать?
Re[2]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 12.08.09 08:08
Оценка:
Здравствуйте, _Dreamer, Вы писали:

_D>а NRVO в Вашем компиляторе есть ? оно здесь срабатывает ?


Стараюсь избегать копирования объектов там, где это не приводит к значительному усложнению кода; но не для того, чтобы выполнить оптимизацию, которую разрешено выполнять компилятору.

(Естественно, это не относится к случаю, когда оптимизация действительно нужна.)
Re[2]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 12.08.09 08:16
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>Скорее всего без возврата по значению.


Почему? В моем примере как раз создание лишних копий vector<string> не может быть соптимизировано компилятором, а с возвратом по значению с точки зрения языка все в порядке, компилятор вправе не создавать копии. Проверять поведение компилятора до выяснения необходимости оптимизации в данном месте не стоит.
Re[2]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 12.08.09 08:25
Оценка:
Здравствуйте, Аноним, Вы писали:

    return count;


Зачем count?
Re[2]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 12.08.09 08:29
Оценка:
Здравствуйте, sokel, Вы писали:

S>При добавлении очередного предложения произойдет реаллокация вектора и все ранее добавленные будут копироваться. По значению. Возможно, лучше будет не vector<vector>, a vector<vector*>.


Возможно. А возможно, что это копирование по значению будет производится 1 раз при запуске программы, а косвенный доступ 1000000 раз.
Re: Заполняем vector<vector<string> >
От: IROV..  
Дата: 12.08.09 08:45
Оценка:
Здравствуйте, igna, Вы писали:

I>Пример внизу заполняет vector<vector<string> > беря значения из некой коллекции:


I>
I>vector<vector<string> > text_to_vvs(Text const* const text)
I>{
I>    vector<vector<string> > vvs;
I>    for (Sentence const* sent = text->FirstSentence(); sent; sent = sent->Next()) {
I>        vector<string> vs;
I>        for (Word const* w = sent->FirstWord(); w; w = w->Next())
I>            vs.push_back(w->Str()); // w->Str() returns char const*
I>        vvs.push_back(vs);
I>    }
I>    return vvs;
I>}
I>


I>Пример реализован прямолинейно, а как бы вы написали?


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

я не волшебник, я только учусь!
Re[2]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 12.08.09 08:55
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>Если итерация быстрая, и элементов не слишком много.

IRO>То думаю будет дешевле посчитать размер, сделать ресайз.
IRO>а потом заполнять без дополнительных реалокаций и копирований.

Ты бы так и сделал с самого начала, еще до проверки того, что такая экономия даст? То есть "посчитать размер, сделать ресайз" это не преждевременная оптимизизация, а избегание преждевременной пессимизации?
Re[3]: Заполняем vector<vector<string> >
От: Alexander G Украина  
Дата: 12.08.09 08:56
Оценка:
Здравствуйте, igna, Вы писали:

I>Ты так пишешь всегда или только тогда, когда нужно cоптимизировать?


Обычно я пишу именно как приведено в исходном сообщении. (разве что w != NULL явно делаю).

С оптимизацией — оборачиваю потенциально большие контейнеры в shared_ptr, но и в этом случае push_back нулевого указателя дешевле ненулевого.
Русский военный корабль идёт ко дну!
Re[3]: Заполняем vector<vector<string> >
От: IROV..  
Дата: 12.08.09 09:48
Оценка:
Здравствуйте, igna, Вы писали:

I>Ты бы так и сделал с самого начала, еще до проверки того, что такая экономия даст? То есть "посчитать размер, сделать ресайз" это не преждевременная оптимизизация, а избегание преждевременной пессимизации?


Коротко:
— Да, обязательно, если бы знал что вычисление размера не очень сложная функция(А я почти уверен что оно так и есть)
— "а избегание преждевременной пессимизации?" — В точку!

Рассуждения:

Ну смотри, я всегда руковожусь правилами не песимизируй и не оптимизируй.

Нужно ли здесь оптимизировать? Раз выложил пост в форум значит — тревожит

вызов New это всегда скверно, копирование тоже скверно, но уже гораздо менее.

Узнать размер у range заданых двумя итераторами тоже скверно.

Теперь вот рассуждаем что из этих зол страшнее.

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

vector<string> vs;
for (Word const* w = sent->FirstWord(); w; w = w->Next())
  vs.push_back(w->Str()); // Ведь даже сдесь при реалокации мы будем перегенерировать новые стринги по несколько раз.
vvs.push_back(vs); //Здесь еще хуже мало того что мы будем копировать вектор в котором содержится "вектор чаров", так мы еще можем попасть на реалокацию масива.



на больших текстовых данных данная оптимизация даст большой бенифит. я не удевлюсь если будет порядка х10
я не волшебник, я только учусь!
Re[3]: Заполняем vector<vector<string> >
От: IROV..  
Дата: 12.08.09 09:51
Оценка:
vector<vector<string> > text_to_vvs(Text const* const text)


Правило хорошего тона,

void text_to_vvs(Text const* const text, vector<vector<string> > & vvs )


З.Ы. не использовать шаблоные типы напрямую (заменить на typedef)

я не волшебник, я только учусь!
Re[3]: Заполняем vector<vector<string> >
От: Юрий Жмеренецкий ICQ 380412032
Дата: 12.08.09 09:58
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Юрий Жмеренецкий, Вы писали:


ЮЖ>>Скорее всего без возврата по значению.


I>Почему?


Я предполагаю что vector<vector<string> > будет членом в каком-либо классе, иначе такое "переливание" выглядит странным. Дальше сразу встает вопрос о коировании объектов такого класса. Вот если бы было так:

struct A : noncopyable
{
  A(Text const* const text) : vec(text_to_vvs(text))
  {}

  //...
private:
  vector<vector<string> > vec;
}


I>В моем примере как раз создание лишних копий vector<string> не может быть соптимизировано компилятором, а с возвратом по значению с точки зрения языка все в порядке, компилятор вправе не создавать копии. Проверять поведение компилятора до выяснения необходимости оптимизации в данном месте не стоит.


Для тяжелых объектов, имхо, должно быть четко определено — кто, и когда является их владельцем (ownership semantics). В случае со 'struct A' выше все понятно — время жизни владельца совпадает с временем жизни подобъекта. Еще остаются случаи 'владеет сейчас' — если владелец разрушен, то и разрушается подобъект, но подобъект можно изменить на другой, забрав у него владение предыдущим, и 'владелец не определен' — это в чистом виде boost::shared_ptr, 'подобъект' (здесь уже не совсем корректный термин) разрушается в тот момент, когда будут разрушены все кто держит ссылку.

Случаи 'один владелец' и 'владеет сейчас' можно реализовать на swap'ах, но тогда семантика становется менее ясной:

// Тот факт что здесь передается владение нужно документировать
// явно, либо смотреть реализацию для выяснения.
A::A(vector<vector<string> >& v)


У вариант со 'struct A' есть еще одна потенциальная проблема: явная связь с text_to_vvs. Это придет к тому что, например, для тестировани функциональности 'A' необходимо будет иметь фейковую реализацию 'Text' (или специально подготовленный объект, а это потянет связанные с 'Text' части), хотя для тестирования достаточно объекта 'vector<vector<string> >'.

text_to_vvs в данном случае я скорее рассматриваю как factory с приблизительно таким видом:

auto_ptr<vector<vector<string> > > text_to_vvs(/*...*/)


Затраты на один вызов 'new' по сравнению с тем что происходит в text_to_vvs — мизерны, присутствует гарантия отсутствия deep copy и т.п. Если заменить auto_ptr на boost::unique_ptr, то семантика становится еще более ясной, + исчезают проблемы, связанные с std::auto_ptr.

PS. Ожидался, наверное ответ на вопрос "как заполнить vector<vector<string> >", но присутствие text_to_vvs увело в другую сторону.
Re[2]: Заполняем vector<vector<string> >
От: IROV..  
Дата: 12.08.09 09:58
Оценка:
Здравствуйте, IROV.., Вы писали:

Сорри не компилировал, писал по приборам

void text_to_vvs( Text const* const text, vector<vector<string> > & vvs )
{
    std::size_t size = 0;
    for (Sentence const* sent = text->FirstSentence(); sent; sent = sent->Next()) 
    {
        ++size;
    }

    vvs.resize( size );

    for( vvs::iterator 
        it = vvs.begin(),
        it_end = vvs.end();
    it != it_end;
    ++it )
    {
        it->resize( size );
    }

    vvs::iterator it_place = vvs.begin();

    for (Sentence const* sent = text->FirstSentence(); sent; sent = sent->Next(), ++it_place ) 
    {
        vvs::value_type::iterator it_place_string = it_place->begin();

        for (Word const* w = sent->FirstWord(); w; w = w->Next(), ++it_place_string )
        {
            *it_place_string = w->Str();
        }
    }
}
я не волшебник, я только учусь!
Re[3]: Заполняем vector<vector<string> >
От: IROV..  
Дата: 12.08.09 10:01
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Юрий Жмеренецкий, Вы писали:


ЮЖ>>Скорее всего без возврата по значению.


I>Почему? В моем примере как раз создание лишних копий vector<string> не может быть соптимизировано компилятором, а с возвратом по значению с точки зрения языка все в порядке, компилятор вправе не создавать копии. Проверять поведение компилятора до выяснения необходимости оптимизации в данном месте не стоит.


http://www.rsdn.ru/forum/cpp/3501445.1.aspx
Автор: IROV..
Дата: 12.08.09


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

я не волшебник, я только учусь!
Re[4]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 12.08.09 10:03
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>Правило хорошего тона,


IRO>void text_to_vvs(Text const* const text, vector<vector<string> > & vvs )

Это правило возможно устарело. VC++, GCC и Intel C++ поддерживают RVO: http://en.wikipedia.org/wiki/Return_value_optimization

IRO>З.Ы. не использовать шаблоные типы напрямую (заменить на typedef)


Так. А это почему?
Re[5]: Заполняем vector<vector<string> >
От: IROV..  
Дата: 12.08.09 10:10
Оценка:
Здравствуйте, igna, Вы писали:

I>Это правило возможно устарело. VC++, GCC и Intel C++ поддерживают RVO: http://en.wikipedia.org/wiki/Return_value_optimization


IRO>>З.Ы. не использовать шаблоные типы напрямую (заменить на typedef)


I>Так. А это почему?


http://www.rsdn.ru/forum/cpp/3501461.1.aspx
Автор: IROV..
Дата: 12.08.09


Это правило хорошего тона распостраняется на контейнеры у которых есть скрытый кэш.

да RVO порезало это правило, например std::list теперь так немного безсмыслено передавать. (Но например мне не впадло передать по ссылке, и душа не болит)

я не волшебник, я только учусь!
Re: Заполняем пользовательский тип
От: igna Россия  
Дата: 12.08.09 10:17
Оценка:
Или как вариант вместо vector<vector<string> > пользовательский тип:

struct my_sentence : vector<string> {
    my_sentence(Sentence const* const sent)
    {
        for (Word const* w = sent->FirstWord(); w; w = w->Next())
            push_back(w->Str()); // w->Str() returns char const*
    }
};

struct my_text : vector<my_sentence> {
    my_text(Text const* const text)
    {
        for (Sentence const* sent = text->FirstSentence(); sent; sent = sent->Next())
            push_back(my_sentence(sent));
    }
};


Вопрос тот же, как бы вы написали в этом случае (при условии, что необходимость оптимизации данного места в программе не выявлена)?
Re[2]: Заполняем пользовательский тип
От: IROV..  
Дата: 12.08.09 10:21
Оценка:
Здравствуйте, igna, Вы писали:

I>Или как вариант вместо vector<vector<string> > пользовательский тип:


I>
I>struct my_sentence : vector<string> {
I>    my_sentence(Sentence const* const sent)
I>    {
I>        for (Word const* w = sent->FirstWord(); w; w = w->Next())
I>            push_back(w->Str()); // w->Str() returns char const*
I>    }
I>};

I>struct my_text : vector<my_sentence> {
I>    my_text(Text const* const text)
I>    {
I>        for (Sentence const* sent = text->FirstSentence(); sent; sent = sent->Next())
I>            push_back(my_sentence(sent));
I>    }
I>};
I>


I>Вопрос тот же, как бы вы написали в этом случае (при условии, что необходимость оптимизации данного места в программе не выявлена)?


Не люблю процесинг в конструкторах

надо конвертнуть Text в my_text -> функция.

я не думаю что my_text и Text это такие базовые вещи для которых это очевидное преобразование.

Text tx;

...

my_text mt( tx );


я не волшебник, я только учусь!
Re[4]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 12.08.09 10:26
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>+ Разьясню, вектор который мы туда передадим может уже быть за ресайзеный(выделено памяти) и тогда внутрения функция ресайз (в тру версии) не будет ничего делать а проскипается, вот эту оптимизацию компилятор в твоем случаее не сделает.


Можно конкретный пример? Не обязательно для приведенного мной случая, а какой-нибудь самый простенький, где "заресайзеный" и "проскипается", и чтобы компилятор оптимизацию не сделал.
Re[4]: Заполняем vector<vector<string> >
От: Alexander G Украина  
Дата: 12.08.09 10:30
Оценка:
AG>С оптимизацией — оборачиваю потенциально большие контейнеры в shared_ptr, но и в этом случае push_back нулевого указателя дешевле ненулевого.

А когда будет emplace_back, выгода от вставки пустого и использования back будет ещё больше:

vector<vector<string> > text_to_vvs(Text const* const text)
{
  vector<vector<string> > vvs;
  for (Sentence const* sent = text->FirstSentence(); sent; sent = sent->Next()) {
    vvs.emplace_back();
    vector<string> & vs = vvs.back();
    for (Word const* w = sent->FirstWord(); w; w = w->Next())
      vs.emplace_back(w->Str()); // w->Str() returns char const*
  }
  return vvs;
}
Русский военный корабль идёт ко дну!
Re[3]: Заполняем пользовательский тип
От: igna Россия  
Дата: 12.08.09 10:36
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>Не люблю процесинг в конструкторах


А я люблю неизменяемые объекты и использую их везде, где только можно.
Re[2]: Заполняем пользовательский тип
От: igna Россия  
Дата: 12.08.09 10:43
Оценка:
I>Или как вариант вместо vector<vector<string> > пользовательский тип:

И тогда определив соответствующие итераторы можно написать так:

struct my_sentence : vector<string> {
    my_sentence(Sentence const* const sent)
        : vector<string>(word_iterator(sent), word_iterator()) {}
};

struct my_text : vector<my_sentence> {
    my_text(Text const* const text)
        : vector<my_sentence>(sentence_iterator(text), sentence_iterator()) {}
};
Re[3]: Заполняем vector<vector<string> >
От: Аноним  
Дата: 12.08.09 12:28
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Аноним, Вы писали:


I>
I>    return count;
I>


I>Зачем count?

А вдруг понадобится узнать сколько все таки элементов скопировалось? Тем более что в функцию можно
передать vvs уже частично заполненый.
Вообще стараюсь, чтобы функция которая копирует данные из объекта одного типа в объект имееющий другой тип что то возвращала.
Почти всегда это было нужно.
Re[2]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 12.08.09 13:18
Оценка:
Здравствуйте, zaufi, Вы писали:

Z>не знаю что такое Text в твоей проге, но если гдето там (в коде до указанного примера) есть буфер (char* или std::string например) с текстом над которым нужно произвести данные зверства...


Нет буфера. Остальное зря писал, значит.
Re[2]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 12.08.09 14:13
Оценка:
Здравствуйте, zaufi, Вы писали:

Z>0) я бы сначла нарезал его boost::algorithm::split'ом на предложения (например по символу '.' в тексте),...


Кстати, предложение может заканчиваться вопросительным или восклицательным знаком. Кроме того оно может окачиваться троеточием, которое не должно приводить к появлению двух пустых предложений. Пустых предложений вообще не должно быть, таким образом двоеточие не являющееся началом троеточия должно приводить к ошибке и выводу соответствующего сообщения. Затем точка внутри кавычек не является концом предложения, причем кавычки могут быть одинарные, двойные и другие определенные в UNICODE. Точка после цифры в начале предложения не является признаком его конца и так далее...

Все-таки не всегда стоит писать свой парсер.
Re[2]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 12.08.09 14:39
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Я бы уволил с работы человека, использующего такие конструкции.


Что за воинствующее мракобесие?

С.7 Multidimensional Arrays

It is not uncommon to need a vector of vectros, a vector of vector of vectors, etc. ...

(The C++ Programming Language, Third Edition, Bjarne Stroustrup)

Re[5]: Заполняем vector<vector<string> >
От: IROV..  
Дата: 12.08.09 14:59
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, IROV.., Вы писали:


IRO>>+ Разьясню, вектор который мы туда передадим может уже быть за ресайзеный(выделено памяти) и тогда внутрения функция ресайз (в тру версии) не будет ничего делать а проскипается, вот эту оптимизацию компилятор в твоем случаее не сделает.


I>Можно конкретный пример? Не обязательно для приведенного мной случая, а какой-нибудь самый простенький, где "заресайзеный" и "проскипается", и чтобы компилятор оптимизацию не сделал.


typedef std::list<std::string> TListFlags;
typedef std::vector<std::string> TVectorFlags;

static void converterListToVectorFlags( const TListFlags & _in, TVectorFlags & _out )
{
    //...
}

class Properties
{
public:
    void addFlags( const TListFlags & _list )
    {
        converterListToVectorFlags( _list, m_flags );
    }

protected:    
    TVectorFlags m_flags;
};


я не волшебник, я только учусь!
Re[6]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 12.08.09 15:12
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>typedef std::list<std::string> TListFlags;
IRO>typedef std::vector<std::string> TVectorFlags;

IRO>static void converterListToVectorFlags( const TListFlags & _in, TVectorFlags & _out )
IRO>{
IRO>    //...
IRO>}

IRO>class Properties
IRO>{
IRO>public:
IRO>    void addFlags( const TListFlags & _list )
IRO>    {
IRO>        converterListToVectorFlags( _list, m_flags );
IRO>    }

IRO>protected:    
IRO>    TVectorFlags m_flags;
IRO>};


Прошу прощения, похоже я недостаточно точно выразился. Под конкретным примером имел в виду код, который можно скомпилировать, запустить и посмотреть, как компилятор не соптимизирует возврат по значению.
Re[3]: Заполняем vector<vector<string> >
От: Шахтер Интернет  
Дата: 12.08.09 17:05
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Шахтер, Вы писали:


Ш>>Я бы уволил с работы человека, использующего такие конструкции.


I>Что за воинствующее мракобесие?


Это не воинствующее мракобесие, а твой воинствующий дилетантизм.

I>

I>С.7 Multidimensional Arrays

I>It is not uncommon to need a vector of vectros, a vector of vector of vectors, etc. ...

I>(The C++ Programming Language, Third Edition, Bjarne Stroustrup)


stl::vector для решения этой задачи не подходит категорически. Потому что в него нельзя складывать объекты с тяжелым оператором копирования -- слишком накладно получается. А использовать дешевые move/swap он не позволяет по дизайну. А здесь два уровня -- исключительно неэффективное решение.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[4]: Заполняем vector<vector<string> >
От: SleepyDrago Украина  
Дата: 12.08.09 20:18
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>stl::vector для решения этой задачи не подходит категорически. Потому что в него нельзя складывать объекты с тяжелым оператором копирования -- слишком накладно получается. А использовать дешевые move/swap он не позволяет по дизайну. А здесь два уровня -- исключительно неэффективное решение.

Самое смешное что rvalue references в VS2010 ускоряют этот ужас раз в 20. И такой код будет и дальше применяться не смотря на массовые расстрелы Недавно на блоге студии был пример ускорения как раз vector<vector<string>>
Re[4]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 13.08.09 04:04
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>stl::vector для решения этой задачи не подходит категорически. Потому что в него нельзя складывать объекты с тяжелым оператором копирования -- слишком накладно получается. А использовать дешевые move/swap он не позволяет по дизайну. А здесь два уровня -- исключительно неэффективное решение.


Ты бы все же посмотрел пример vector of vectors у Страуструпа. Можешь еще примечание на полях сделать, мол автор есть дилетант и предлагаемое им решение неэффективно.
Re[5]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 13.08.09 04:08
Оценка:
Здравствуйте, SleepyDrago, Вы писали:

SD>Самое смешное что rvalue references в VS2010 ускоряют этот ужас раз в 20. И такой код будет и дальше применяться не смотря на массовые расстрелы Недавно на блоге студии был пример ускорения как раз vector<vector<string>>


Ты за или против использования vector<vector<string>>?
Re[6]: Заполняем vector<vector<string> >
От: SleepyDrago Украина  
Дата: 13.08.09 10:01
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, SleepyDrago, Вы писали:


SD>>Самое смешное что rvalue references в VS2010 ускоряют этот ужас раз в 20. И такой код будет и дальше применяться не смотря на массовые расстрелы Недавно на блоге студии был пример ускорения как раз vector<vector<string>>


I>Ты за или против использования vector<vector<string>>?

Разумеется я против. Просто я признаю что есть софт, который этим пользуется тк у них нет требований по скорости и потребляемым ресурсам. И для тех кто пользуется подобными конструкциями в мс сообщали радостные новости http://blogs.msdn.com/vcblog/archive/2009/06/23/stl-performance.aspx
Re[7]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 13.08.09 10:08
Оценка:
Здравствуйте, SleepyDrago, Вы писали:

SD>Разумеется я против.


А если vector<vector<int> > вместо vector<vector<string> >, это меняет дело?
Re[8]: Заполняем vector<vector<string> >
От: SleepyDrago Украина  
Дата: 13.08.09 10:14
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, SleepyDrago, Вы писали:


SD>>Разумеется я против.


I>А если vector<vector<int> > вместо vector<vector<string> >, это меняет дело?

Нет ессно.

зы. Фрагментация памяти. Произвольный доступ. В общем это лучше писать на (подставьте сюда самое модное) чем на ++ если такие мягкие требования.
Re[9]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 13.08.09 10:22
Оценка:
Здравствуйте, SleepyDrago, Вы писали:

I>>А если vector<vector<int> > вместо vector<vector<string> >, это меняет дело?

SD>Нет ессно.

Так... А пример использования vector<vector<int> > у Страуструпа, на который я давал ссылку
Автор: igna
Дата: 12.08.09
, видел?
Re[10]: Заполняем vector<vector<string> >
От: SleepyDrago Украина  
Дата: 13.08.09 10:48
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, SleepyDrago, Вы писали:


I>>>А если vector<vector<int> > вместо vector<vector<string> >, это меняет дело?

SD>>Нет ессно.

I>Так... А пример использования vector<vector<int> > у Страуструпа, на который я давал ссылку
Автор: igna
Дата: 12.08.09
, видел?

там где

I first show how to use the standard library vector class. Next, I present multidimensional arrays as they appear in C and C++ programs using only built-in facilities

?
Ну так тут ясно написано. Сначала для самых маленьких, кто не знает как пользоваться вектором. Потом только со встроенными средствами. Это же не рекомендованный способ решения, а всего лишь иллюстрация к стд библиотеке. Где вы здесь видите анализ временной сложности типичных операций или оценку требуемой памяти ? Попробуйте прикинуть — сразу поймете почему у тов. Шахтера и не только него совсем нет желания иметь с этим дело. Грамотное решение предложил zaufi и оно сводится к построению пары индексов над исходным текстом.
Удачи!
Re[3]: Заполняем vector<vector<string> >
От: sokel Россия  
Дата: 13.08.09 11:48
Оценка:
Здравствуйте, igna, Вы писали:

I>Возможно. А возможно, что это копирование по значению будет производится 1 раз при запуске программы, а косвенный доступ 1000000 раз.


Если вектора слов будут существовать только в рамках контейнера, можно попробовать такой вот финт:

// самопальный move_semantic :)
struct sentence : public vector<string> 
{
    sentence() {};
    sentence(const sentence& other) { swap(const_cast<sentence&>(other)); }
};
typedef vector<sentence> sentence_list;
Re[11]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 13.08.09 11:48
Оценка:
SD>Ну так тут ясно написано. Сначала для самых маленьких, кто не знает как пользоваться вектором. Потом только со встроенными средствами.

Нда... Наверное если бы ты прочитал до конца, то заметил бы, что раздел про "встроенные средства" (C.7.2 Arrays) начинается словами "The built-in arrays are a major source of errors", а следующий за ним раздел про многомерные "встроенные средства" (C.7.3 Passing Multidimensional Arrays) заканчивается словами "The standard vector doesn't suffer from these problems".
Re[5]: Заполняем vector<vector<string> >
От: Шахтер Интернет  
Дата: 13.08.09 18:10
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Шахтер, Вы писали:


Ш>>stl::vector для решения этой задачи не подходит категорически. Потому что в него нельзя складывать объекты с тяжелым оператором копирования -- слишком накладно получается. А использовать дешевые move/swap он не позволяет по дизайну. А здесь два уровня -- исключительно неэффективное решение.


I>Ты бы все же посмотрел пример vector of vectors у Страуструпа. Можешь еще примечание на полях сделать, мол автор есть дилетант и предлагаемое им решение неэффективно.


Что дилетант не скажу, а что неэффективно -- скажу. И это не моё частное мнение, а объективная реальность, с которой нужно всё-таки считаться.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[11]: Заполняем vector<vector<string> >
От: Шахтер Интернет  
Дата: 13.08.09 18:19
Оценка:
Здравствуйте, SleepyDrago, Вы писали:

SD>Здравствуйте, igna, Вы писали:


I>>Здравствуйте, SleepyDrago, Вы писали:


I>>>>А если vector<vector<int> > вместо vector<vector<string> >, это меняет дело?

SD>>>Нет ессно.

I>>Так... А пример использования vector<vector<int> > у Страуструпа, на который я давал ссылку
Автор: igna
Дата: 12.08.09
, видел?

SD>там где

SD>

SD>I first show how to use the standard library vector class. Next, I present multidimensional arrays as they appear in C and C++ programs using only built-in facilities

SD>?
SD>Ну так тут ясно написано. Сначала для самых маленьких, кто не знает как пользоваться вектором. Потом только со встроенными средствами. Это же не рекомендованный способ решения, а всего лишь иллюстрация к стд библиотеке. Где вы здесь видите анализ временной сложности типичных операций или оценку требуемой памяти ? Попробуйте прикинуть — сразу поймете почему у тов. Шахтера и не только него совсем нет желания иметь с этим дело. Грамотное решение предложил zaufi и оно сводится к построению пары индексов над исходным текстом.
SD>Удачи!

У меня был реальный случай. Пришел студент на практику. Я ему дал задание сделать FFT. Он написал код, после чего я попросил его замерить производительность и сравнить с прямой реализацией (с квадратичной сложностью). Быстрое преобразование на поверку оказалось медленнее медленной. Причина -- в бездумном использовании vector<vector<double> >. Собственно говоря, этот (и другие), случаи наглядно демонстрируют, что легкомысленное использование библиотек без ясного понимания их устройства легко приводит к неприемлимо неэффективным решениям. Всё-таки программироание начинается с умения писать циклы, оперировать указателями, правильно вызывать функции malloc/free и open/close и.т.п. базовым векщам.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[6]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 14.08.09 04:57
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Что дилетант не скажу, а что неэффективно -- скажу.


Ну и зря ты так огульно. Если vector of vector используется правильно и к месту, никакой особой неэффективности по сравнению с массивами не будет. Возможно мой первый пример
Автор: igna
Дата: 12.08.09
подействовал на тебя как красная тряпка. Ну так я специально так написал — что вижу, то пою — чтобы узнать, удовлетворяет ли такое прямолинейное решение кого-нибудь и как пишут те, кого не удовлетворяет. Мое предпочтительное решение здесь
Автор: igna
Дата: 12.08.09
.
Re[7]: Заполняем vector<vector<string> >
От: IROV..  
Дата: 14.08.09 07:44
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Шахтер, Вы писали:


Ш>>Что дилетант не скажу, а что неэффективно -- скажу.


I>Ну и зря ты так огульно. Если vector of vector используется правильно и к месту, никакой особой неэффективности по сравнению с массивами не будет. Возможно мой первый пример
Автор: igna
Дата: 12.08.09
подействовал на тебя как красная тряпка. Ну так я специально так написал — что вижу, то пою — чтобы узнать, удовлетворяет ли такое прямолинейное решение кого-нибудь и как пишут те, кого не удовлетворяет. Мое предпочтительное решение здесь
Автор: igna
Дата: 12.08.09
.

Твое решение это теже яйца только с боку (красиво заэвулированое vvs)
я не волшебник, я только учусь!
Re[8]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 14.08.09 08:13
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>Твое решение это теже яйца только с боку (красиво заэвулированое vvs)


Отнюдь нет. Если word_iterator::value_typechar const*, а sentence_iterator::value_typeSentence const*, никаких лишних копирований не происходит.
Re[9]: Заполняем vector<vector<string> >
От: IROV..  
Дата: 14.08.09 08:23
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, IROV.., Вы писали:


IRO>>Твое решение это теже яйца только с боку (красиво заэвулированое vvs)


I>Отнюдь нет. Если word_iterator::value_typechar const*, а sentence_iterator::value_typeSentence const*, никаких лишних копирований не происходит.


ну да ты соптимизировал std::string но vv осталось
я не волшебник, я только учусь!
Re[10]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 14.08.09 08:36
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>ну да ты соптимизировал std::string но vv осталось


Так нет же. Обрати внимание на то, что sentence_iterator::value_type это Sentence const*, а не my_sentence.
Re[11]: Заполняем vector<vector<string> >
От: IROV..  
Дата: 14.08.09 11:11
Оценка:
Здравствуйте, igna, Вы писали:

I>Так нет же. Обрати внимание на то, что sentence_iterator::value_type это Sentence const*, а не my_sentence.

struct my_sentence : vector<string>
struct my_text : vector<my_sentence>

вот что я вижу.
я не волшебник, я только учусь!
Re[12]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 14.08.09 11:24
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>struct my_sentence : vector<string>
IRO>struct my_text : vector<my_sentence>

IRO> вот что я вижу.

Что, что по структуре my_text это по сути тот же vector<vector<string> >? Да, но при заполнении его так, как я показал, не происходит ни одного лишнего копирования.
Re[13]: Заполняем vector<vector<string> >
От: IROV..  
Дата: 14.08.09 13:13
Оценка:
Здравствуйте, igna, Вы писали:

I>Что, что по структуре my_text это по сути тот же vector<vector<string> >? Да, но при заполнении его так, как я показал, не происходит ни одного лишнего копирования.


А ты знаешь что при конструирование вектора, двумя итераторами, находится distance, делается resize?
тоесть все тоже самое что я тебе написал.

на самом деле ты можешь просто сделать stl like proxy iterator для
text->FirstSentence(); sent; sent = sent->Next()

я не волшебник, я только учусь!
Re[14]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 14.08.09 13:25
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>А ты знаешь что при конструирование вектора, двумя итераторами, находится distance, делается resize?


И что? Это же не приваивание, а конструктор. Лишних размещений нет.
Re[15]: Заполняем vector<vector<string> >
От: IROV..  
Дата: 14.08.09 13:58
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, IROV.., Вы писали:


IRO>>А ты знаешь что при конструирование вектора, двумя итераторами, находится distance, делается resize?


I>И что? Это же не приваивание, а конструктор. Лишних размещений нет.

ты просто написал stl-like proxy iterator для твоего intrusive list,

если развернуть то ты получишь тоже самое

get_size
resize
placement



еще можно поигратся развернув память vv -> v

vector<vector::iterator> text;
vector<char const *> worlds;

но при этом нужно знать специфику
я не волшебник, я только учусь!
Re[16]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 14.08.09 14:14
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>ты просто написал stl-like proxy iterator для твоего intrusive list,


IRO>если развернуть то ты получишь тоже самое


IRO>get_size

IRO>resize
IRO>placement

IRO>


IRO>еще можно поигратся развернув память vv -> v


IRO>vector<vector::iterator> text;

IRO>vector<char const *> worlds;

IRO>но при этом нужно знать специфику


Извини, из всего этого я так и не понял: ты все еще считаешь, что в этом примере
Автор: igna
Дата: 12.08.09
есть избыточные размещения и копирования?
Re[17]: Заполняем vector<vector<string> >
От: IROV..  
Дата: 14.08.09 14:21
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, IROV.., Вы писали:


IRO>>ты просто написал stl-like proxy iterator для твоего intrusive list,


IRO>>если развернуть то ты получишь тоже самое


IRO>>get_size

IRO>>resize
IRO>>placement

IRO>>


IRO>>еще можно поигратся развернув память vv -> v


IRO>>vector<vector::iterator> text;

IRO>>vector<char const *> worlds;

IRO>>но при этом нужно знать специфику


I>Извини, из всего этого я так и не понял: ты все еще считаешь, что в этом примере
Автор: igna
Дата: 12.08.09
есть избыточные размещения и копирования?

Ну я бы сказал что это достаточно оптимизированый код. Можно лучше но нужно ли?
я не волшебник, я только учусь!
Re[18]: Заполняем vector<vector<string> >
От: igna Россия  
Дата: 14.08.09 14:24
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>Ну я бы сказал что это достаточно оптимизированый код. Можно лучше но нужно ли?


А можно сделать меньше размещений и копирований?
Re[19]: Заполняем vector<vector<string> >
От: IROV..  
Дата: 14.08.09 15:00
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, IROV.., Вы писали:


IRO>>Ну я бы сказал что это достаточно оптимизированый код. Можно лучше но нужно ли?


I>А можно сделать меньше размещений и копирований?

размещения и копирование я думаю это одно и тоже если конечно под копированием не понимать (реалокацию существующих данных)

можно уменьшить вызовов new, сделав 2 вектора вместо vv.

я уже писал выше об этом.
я не волшебник, я только учусь!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.