Здравствуйте, igna, Вы писали:
I>Пример внизу заполняет vector<vector<string> > беря значения из некой коллекции:
I>Пример реализован прямолинейно, а как бы вы написали?
Я бы уволил с работы человека, использующего такие конструкции.
I>Прошу прощения, похоже я недостаточно точно выразился. Под конкретным примером имел в виду код, который можно скомпилировать, запустить и посмотреть, как компилятор не соптимизирует возврат по значению.
Здравствуйте, 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
полностью с вами согласен — правда можно чуток поковырять детали
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. Но на практике часто можно воспользоваться тем, что данные ограничены по длине.
Здравствуйте, 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>
Здравствуйте, igna, Вы писали:
I>Пример внизу заполняет vector<vector<string> > беря значения из некой коллекции: I>Пример реализован прямолинейно, а как бы вы написали?
а NRVO в Вашем компиляторе есть ? оно здесь срабатывает ?
а то я бы написал влоб —
Здравствуйте, igna, Вы писали:
I>Пример реализован прямолинейно, а как бы вы написали?
При добавлении очередного предложения произойдет реаллокация вектора и все ранее добавленные будут копироваться. По значению. Возможно, лучше будет не vector<vector>, a vector<vector*>.
Здравствуйте, _Dreamer, Вы писали:
_D>а NRVO в Вашем компиляторе есть ? оно здесь срабатывает ?
Стараюсь избегать копирования объектов там, где это не приводит к значительному усложнению кода; но не для того, чтобы выполнить оптимизацию, которую разрешено выполнять компилятору.
(Естественно, это не относится к случаю, когда оптимизация действительно нужна.)
Здравствуйте, Юрий Жмеренецкий, Вы писали:
ЮЖ>Скорее всего без возврата по значению.
Почему? В моем примере как раз создание лишних копий vector<string> не может быть соптимизировано компилятором, а с возвратом по значению с точки зрения языка все в порядке, компилятор вправе не создавать копии. Проверять поведение компилятора до выяснения необходимости оптимизации в данном месте не стоит.
Здравствуйте, sokel, Вы писали:
S>При добавлении очередного предложения произойдет реаллокация вектора и все ранее добавленные будут копироваться. По значению. Возможно, лучше будет не vector<vector>, a vector<vector*>.
Возможно. А возможно, что это копирование по значению будет производится 1 раз при запуске программы, а косвенный доступ 1000000 раз.
Здравствуйте, 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>Пример реализован прямолинейно, а как бы вы написали?
Если итерация быстрая, и элементов не слишком много.
То думаю будет дешевле посчитать размер, сделать ресайз.
а потом заполнять без дополнительных реалокаций и копирований.
Здравствуйте, IROV.., Вы писали:
IRO>Если итерация быстрая, и элементов не слишком много. IRO>То думаю будет дешевле посчитать размер, сделать ресайз. IRO>а потом заполнять без дополнительных реалокаций и копирований.
Ты бы так и сделал с самого начала, еще до проверки того, что такая экономия даст? То есть "посчитать размер, сделать ресайз" это не преждевременная оптимизизация, а избегание преждевременной пессимизации?
Здравствуйте, 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
Здравствуйте, igna, Вы писали:
I>Здравствуйте, Юрий Жмеренецкий, Вы писали:
ЮЖ>>Скорее всего без возврата по значению.
I>Почему?
Я предполагаю что vector<vector<string> > будет членом в каком-либо классе, иначе такое "переливание" выглядит странным. Дальше сразу встает вопрос о коировании объектов такого класса. Вот если бы было так:
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 с приблизительно таким видом:
Затраты на один вызов 'new' по сравнению с тем что происходит в text_to_vvs — мизерны, присутствует гарантия отсутствия deep copy и т.п. Если заменить auto_ptr на boost::unique_ptr, то семантика становится еще более ясной, + исчезают проблемы, связанные с std::auto_ptr.
PS. Ожидался, наверное ответ на вопрос "как заполнить vector<vector<string> >", но присутствие text_to_vvs увело в другую сторону.
Здравствуйте, igna, Вы писали:
I>Здравствуйте, Юрий Жмеренецкий, Вы писали:
ЮЖ>>Скорее всего без возврата по значению.
I>Почему? В моем примере как раз создание лишних копий vector<string> не может быть соптимизировано компилятором, а с возвратом по значению с точки зрения языка все в порядке, компилятор вправе не создавать копии. Проверять поведение компилятора до выяснения необходимости оптимизации в данном месте не стоит.
+ Разьясню, вектор который мы туда передадим может уже быть за ресайзеный(выделено памяти) и тогда внутрения функция ресайз (в тру версии) не будет ничего делать а проскипается, вот эту оптимизацию компилятор в твоем случаее не сделает.
Здравствуйте, igna, Вы писали:
I>Это правило возможно устарело. VC++, GCC и Intel C++ поддерживают RVO: http://en.wikipedia.org/wiki/Return_value_optimization
IRO>>З.Ы. не использовать шаблоные типы напрямую (заменить на typedef)
I>Так. А это почему?
Это правило хорошего тона распостраняется на контейнеры у которых есть скрытый кэш.
да RVO порезало это правило, например std::list теперь так немного безсмыслено передавать. (Но например мне не впадло передать по ссылке, и душа не болит)
Здравствуйте, IROV.., Вы писали:
IRO>+ Разьясню, вектор который мы туда передадим может уже быть за ресайзеный(выделено памяти) и тогда внутрения функция ресайз (в тру версии) не будет ничего делать а проскипается, вот эту оптимизацию компилятор в твоем случаее не сделает.
Можно конкретный пример? Не обязательно для приведенного мной случая, а какой-нибудь самый простенький, где "заресайзеный" и "проскипается", и чтобы компилятор оптимизацию не сделал.
Здравствуйте, igna, Вы писали:
I>Здравствуйте, Аноним, Вы писали:
I>
I> return count;
I>
I>Зачем count?
А вдруг понадобится узнать сколько все таки элементов скопировалось? Тем более что в функцию можно
передать vvs уже частично заполненый.
Вообще стараюсь, чтобы функция которая копирует данные из объекта одного типа в объект имееющий другой тип что то возвращала.
Почти всегда это было нужно.
Здравствуйте, zaufi, Вы писали:
Z>не знаю что такое Text в твоей проге, но если гдето там (в коде до указанного примера) есть буфер (char* или std::string например) с текстом над которым нужно произвести данные зверства...
Здравствуйте, zaufi, Вы писали:
Z>0) я бы сначла нарезал его boost::algorithm::split'ом на предложения (например по символу '.' в тексте),...
Кстати, предложение может заканчиваться вопросительным или восклицательным знаком. Кроме того оно может окачиваться троеточием, которое не должно приводить к появлению двух пустых предложений. Пустых предложений вообще не должно быть, таким образом двоеточие не являющееся началом троеточия должно приводить к ошибке и выводу соответствующего сообщения. Затем точка внутри кавычек не является концом предложения, причем кавычки могут быть одинарные, двойные и другие определенные в UNICODE. Точка после цифры в начале предложения не является признаком его конца и так далее...
Здравствуйте, igna, Вы писали:
I>Здравствуйте, IROV.., Вы писали:
IRO>>+ Разьясню, вектор который мы туда передадим может уже быть за ресайзеный(выделено памяти) и тогда внутрения функция ресайз (в тру версии) не будет ничего делать а проскипается, вот эту оптимизацию компилятор в твоем случаее не сделает.
I>Можно конкретный пример? Не обязательно для приведенного мной случая, а какой-нибудь самый простенький, где "заресайзеный" и "проскипается", и чтобы компилятор оптимизацию не сделал.
Прошу прощения, похоже я недостаточно точно выразился. Под конкретным примером имел в виду код, который можно скомпилировать, запустить и посмотреть, как компилятор не соптимизирует возврат по значению.
Здравствуйте, 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 он не позволяет по дизайну. А здесь два уровня -- исключительно неэффективное решение.
Здравствуйте, Шахтер, Вы писали:
Ш>stl::vector для решения этой задачи не подходит категорически. Потому что в него нельзя складывать объекты с тяжелым оператором копирования -- слишком накладно получается. А использовать дешевые move/swap он не позволяет по дизайну. А здесь два уровня -- исключительно неэффективное решение.
Самое смешное что rvalue references в VS2010 ускоряют этот ужас раз в 20. И такой код будет и дальше применяться не смотря на массовые расстрелы Недавно на блоге студии был пример ускорения как раз vector<vector<string>>
Здравствуйте, Шахтер, Вы писали:
Ш>stl::vector для решения этой задачи не подходит категорически. Потому что в него нельзя складывать объекты с тяжелым оператором копирования -- слишком накладно получается. А использовать дешевые move/swap он не позволяет по дизайну. А здесь два уровня -- исключительно неэффективное решение.
Ты бы все же посмотрел пример vector of vectors у Страуструпа. Можешь еще примечание на полях сделать, мол автор есть дилетант и предлагаемое им решение неэффективно.
Здравствуйте, SleepyDrago, Вы писали:
SD>Самое смешное что rvalue references в VS2010 ускоряют этот ужас раз в 20. И такой код будет и дальше применяться не смотря на массовые расстрелы Недавно на блоге студии был пример ускорения как раз vector<vector<string>>
Ты за или против использования vector<vector<string>>?
Здравствуйте, 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
Здравствуйте, igna, Вы писали:
I>Здравствуйте, SleepyDrago, Вы писали:
SD>>Разумеется я против.
I>А если vector<vector<int> > вместо vector<vector<string> >, это меняет дело?
Нет ессно.
зы. Фрагментация памяти. Произвольный доступ. В общем это лучше писать на (подставьте сюда самое модное) чем на ++ если такие мягкие требования.
Здравствуйте, igna, Вы писали:
I>Здравствуйте, SleepyDrago, Вы писали:
I>>>А если vector<vector<int> > вместо vector<vector<string> >, это меняет дело? SD>>Нет ессно.
I>Так... А пример использования vector<vector<int> > у Страуструпа, на который я давал ссылку
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 и оно сводится к построению пары индексов над исходным текстом.
Удачи!
Здравствуйте, igna, Вы писали:
I>Возможно. А возможно, что это копирование по значению будет производится 1 раз при запуске программы, а косвенный доступ 1000000 раз.
Если вектора слов будут существовать только в рамках контейнера, можно попробовать такой вот финт:
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".
Здравствуйте, igna, Вы писали:
I>Здравствуйте, Шахтер, Вы писали:
Ш>>stl::vector для решения этой задачи не подходит категорически. Потому что в него нельзя складывать объекты с тяжелым оператором копирования -- слишком накладно получается. А использовать дешевые move/swap он не позволяет по дизайну. А здесь два уровня -- исключительно неэффективное решение.
I>Ты бы все же посмотрел пример vector of vectors у Страуструпа. Можешь еще примечание на полях сделать, мол автор есть дилетант и предлагаемое им решение неэффективно.
Что дилетант не скажу, а что неэффективно -- скажу. И это не моё частное мнение, а объективная реальность, с которой нужно всё-таки считаться.
Здравствуйте, SleepyDrago, Вы писали:
SD>Здравствуйте, igna, Вы писали:
I>>Здравствуйте, SleepyDrago, Вы писали:
I>>>>А если vector<vector<int> > вместо vector<vector<string> >, это меняет дело? SD>>>Нет ессно.
I>>Так... А пример использования vector<vector<int> > у Страуструпа, на который я давал ссылку
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 и.т.п. базовым векщам.
Здравствуйте, Шахтер, Вы писали:
Ш>Что дилетант не скажу, а что неэффективно -- скажу.
Ну и зря ты так огульно. Если vector of vector используется правильно и к месту, никакой особой неэффективности по сравнению с массивами не будет. Возможно мой первый пример
подействовал на тебя как красная тряпка. Ну так я специально так написал — что вижу, то пою — чтобы узнать, удовлетворяет ли такое прямолинейное решение кого-нибудь и как пишут те, кого не удовлетворяет. Мое предпочтительное решение здесь
Здравствуйте, igna, Вы писали:
I>Здравствуйте, Шахтер, Вы писали:
Ш>>Что дилетант не скажу, а что неэффективно -- скажу.
I>Ну и зря ты так огульно. Если vector of vector используется правильно и к месту, никакой особой неэффективности по сравнению с массивами не будет. Возможно мой первый пример
подействовал на тебя как красная тряпка. Ну так я специально так написал — что вижу, то пою — чтобы узнать, удовлетворяет ли такое прямолинейное решение кого-нибудь и как пишут те, кого не удовлетворяет. Мое предпочтительное решение здесь
Здравствуйте, igna, Вы писали:
I>Здравствуйте, IROV.., Вы писали:
IRO>>Твое решение это теже яйца только с боку (красиво заэвулированое vvs)
I>Отнюдь нет. Если word_iterator::value_type — char const*, а sentence_iterator::value_type — Sentence const*, никаких лишних копирований не происходит.
ну да ты соптимизировал std::string но vv осталось
Что, что по структуре my_text это по сути тот же vector<vector<string> >? Да, но при заполнении его так, как я показал, не происходит ни одного лишнего копирования.
Здравствуйте, igna, Вы писали:
I>Что, что по структуре my_text это по сути тот же vector<vector<string> >? Да, но при заполнении его так, как я показал, не происходит ни одного лишнего копирования.
А ты знаешь что при конструирование вектора, двумя итераторами, находится distance, делается resize?
тоесть все тоже самое что я тебе написал.
на самом деле ты можешь просто сделать stl like proxy iterator для text->FirstSentence(); sent; sent = sent->Next()
Здравствуйте, igna, Вы писали:
I>Здравствуйте, IROV.., Вы писали:
IRO>>А ты знаешь что при конструирование вектора, двумя итераторами, находится distance, делается resize?
I>И что? Это же не приваивание, а конструктор. Лишних размещений нет.
ты просто написал stl-like proxy iterator для твоего intrusive list,
Здравствуйте, 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, Вы писали:
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, Вы писали:
I>Здравствуйте, IROV.., Вы писали:
IRO>>Ну я бы сказал что это достаточно оптимизированый код. Можно лучше но нужно ли?
I>А можно сделать меньше размещений и копирований?
размещения и копирование я думаю это одно и тоже если конечно под копированием не понимать (реалокацию существующих данных)
можно уменьшить вызовов new, сделав 2 вектора вместо vv.