Здравствуйте, agendus, Вы писали:
A>Так вот, сначала такие поля я обрабатывал стандартными функциями C для работы с C-строками. Потом надоело писать каждый раз громоздкие операторы типа A>
A>TCHAR chTemp[MAX_PATH];
A>wcscpy(chTemp, vNode.m_sItemFullName); // запоминаем полное имя тэга
A>wcscpy(vNode.m_sItemFullName, vParentNode.m_sItemName);
A>wcscat(vNode.m_sItemFullName, TAG_SEPARATOR);
A>wcscat(vNode.m_sItemFullName, chTemp);
A>
NULL-termianted — зло. И с т.з. корректонсти (обеспечение правильного освобождения, отсутсвия переполнений), и с т.з. эффективности (каждый wcscat ищет нуль для себя).
A>Когда какой вариант лучше использовать?
CString.
Русский военный корабль идёт ко дну!
Re[4]: вопрос о вариантах использования строк в C++
A>>Вот за это я и зацеплюсь. Почему в ряде предпочтений std::wstring на 2-м месте, а не на 1-м? За счет чего? B>Ну, о неудобстве/некачественности std::string спорили много — попробуй поискать по сайту. B>Чем этот класс не нравится мне (из последних ярких впечатлений): новомодные оптимизации для маленьких строк. Из-за этого размер объекта string становится совсем немаленьким. В STLPort эту фичу можно хотя бы отключить...
Ну так и юзайте stlport, в чем проблема то?
B>Опять же из-за этой фичи копирование объектов string с помошью memcpy приводит к самым печальным последствиям.
Вы копируете ОБЪЕКТЫ при помощи memcpy, я праивльно понял? Расстрелять.
B>Пример: в одном из проектов используется почтовый клиент, стянутный то ли с codeproject, то ли еще откуда-то. Так вот там объекты std::string храняться в MFC-контейнере CSimpleMap, а он при реаллокациях использует memcpy. Мы не будем спорить, насколько это законно с точки зрения стандарта — факт в том, что все это работало до перехода на новую реализацию STL, а пототм случился бабах.
Расстрелять.
B>В общем я использую стандартные строки только в крайнем случае, CString мне нравится больше.
А у нас проект на почти миллион строк, юзаем std:(w)string. Критичность перфоманса такая что вашему почтовому клиенту и не снилось.
Здравствуйте, agendus, Вы писали:
A>Здравствуйте, уважаемые форумчане. A>Помогите разложить по полочкам и разобраться.
A>Вот есть стандартные C-строки, представляемые как массив char/wchar_t. A>Есть контейнеры в STL для работы со строками, есть класс CString в MFC. A>Можно еще и свой класс-обертку написать.
A>Когда какой вариант лучше использовать?
A>Вот например, пишу я приложение на VC++, без использования MFC. A>Есть классы, поля которых содержат строковые данные. Чтобы не утяжелять класс, это поле определяется типом не std::wstring, а просто LPWSTR.
A>Так вот, сначала такие поля я обрабатывал стандартными функциями C для работы с C-строками. Потом надоело писать каждый раз громоздкие операторы типа A>
A>TCHAR chTemp[MAX_PATH];
A>wcscpy(chTemp, vNode.m_sItemFullName); // запоминаем полное имя тэга
A>wcscpy(vNode.m_sItemFullName, vParentNode.m_sItemName);
A>wcscat(vNode.m_sItemFullName, TAG_SEPARATOR);
A>wcscat(vNode.m_sItemFullName, chTemp);
A>
A>и я стал делать вот так: A>
A>std::wstring strTemp;
A>strTemp.assign(vNode.m_sItemFullName); // запоминаем полное имя strFullID.append(vParentNode.m_sItemName);
A>strFullID.append(TAG_SEPARATOR);
A>strFullID.append( strTemp.c_str() );
A>
A>Делается все одно и тоже, просто во 2-м случае немного утяжеляется. Как лучше все-таки?
Решение как всегда сильно зависит от решаемой задачи и требований к ней.
При написании XML-парсера и типичного приложения решения могут быть очень разными.
1) какие требования к производительности / использованию памяти?
2) каков характерный ожидаемый размер строк?
3) есть ли информация о специфике строк которые будут хранится?
( м.б. они ограничены по длине? Часто встречаются одинаковые значения? Как часто встречаются различные операции со строками )
4) будет ли процедура тесно привязана к какому либо фреймвокру (MFC/Qt/...)?
5) предполагается ли предоставление C-like интерфейса для данного класса?
В общем случае, ИМХО, std::string/wstring предпочтительнее char[], а больший размер экземпляра класса компенсируется производительностью использования.
Строки MFC/Qt — использую только если они продиктованы окружением.
Свои велосипеды и/или char[] — только если профайлер показал проблемы.
Re[5]: вопрос о вариантах использования строк в C++
Аноним 639 пишет:
> B>Пример: в одном из проектов используется почтовый клиент, стянутный то > ли с codeproject, то ли еще откуда-то. Так вот там объекты std::string > храняться в MFC-контейнере CSimpleMap, а он при реаллокациях использует > memcpy. Мы не будем спорить, насколько это законно с точки зрения > стандарта — факт в том, что все это работало до перехода на новую > реализацию STL, а пототм случился бабах. > Расстрелять.
+1, вместе со всем этим codeproject.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: вопрос о вариантах использования строк в C++
Здравствуйте, agendus, Вы писали:
A>По использованию памяти. Приложение — сервис, будет работать в режиме 24/7 (постоянно то есть). При запуске может создаваться до нескольких сотен экземпляров класса типа A>
A>class COpcNode
A>
OPC сервер или клиент?
Используй std::[w]string и не компостируй себе и людям мозг. Даже близко не та задача, чтобы о памяти под строки беспокоиться.
Оптимизировать использование памяти, однако, тут можно и нужно, но оптимизация эта должна лежать в другой плоскости.
agendus пишет:
> В случае std::wstring смущает, что утяжеляется функциональность. > Все-таки под класс больше памяти отводится.
Просто не думай об этом.
На самом деле "под класс (wstring) больше памяти отводится" --
просто неправда. В некоторых случаях ты память даже будещь экономить.
Posted via RSDN NNTP Server 2.1 beta
Re[5]: вопрос о вариантах использования строк в C++
Здравствуйте, Аноним, Вы писали:
A>>>Вот за это я и зацеплюсь. Почему в ряде предпочтений std::wstring на 2-м месте, а не на 1-м? За счет чего? B>>Ну, о неудобстве/некачественности std::string спорили много — попробуй поискать по сайту. B>>Чем этот класс не нравится мне (из последних ярких впечатлений): новомодные оптимизации для маленьких строк. Из-за этого размер объекта string становится совсем немаленьким. В STLPort эту фичу можно хотя бы отключить... А>Ну так и юзайте stlport, в чем проблема то?
Используем.
B>>Опять же из-за этой фичи копирование объектов string с помошью memcpy приводит к самым печальным последствиям. А>Вы копируете ОБЪЕКТЫ при помощи memcpy, я праивльно понял? Расстрелять.
Я — нет. Читать нужно внимательнее.
B>>Пример: в одном из проектов используется почтовый клиент, стянутный то ли с codeproject, то ли еще откуда-то. Так вот там объекты std::string храняться в MFC-контейнере CSimpleMap, а он при реаллокациях использует memcpy. Мы не будем спорить, насколько это законно с точки зрения стандарта — факт в том, что все это работало до перехода на новую реализацию STL, а пототм случился бабах. А>Расстрелять.
Можете неписать это разработчикам MFC.
B>>В общем я использую стандартные строки только в крайнем случае, CString мне нравится больше. А>А у нас проект на почти миллион строк, юзаем std:(w)string. Критичность перфоманса такая что вашему почтовому клиенту и не снилось.
Ну, я рад за Вас. Кстати, учитываю Вашу внимательность при прочтении, клиент не наш.
Здравствуйте, уважаемые форумчане.
Помогите разложить по полочкам и разобраться.
Вот есть стандартные C-строки, представляемые как массив char/wchar_t.
Есть контейнеры в STL для работы со строками, есть класс CString в MFC.
Можно еще и свой класс-обертку написать.
Когда какой вариант лучше использовать?
Вот например, пишу я приложение на VC++, без использования MFC.
Есть классы, поля которых содержат строковые данные. Чтобы не утяжелять класс, это поле определяется типом не std::wstring, а просто LPWSTR.
Так вот, сначала такие поля я обрабатывал стандартными функциями C для работы с C-строками. Потом надоело писать каждый раз громоздкие операторы типа
TCHAR chTemp[MAX_PATH];
wcscpy(chTemp, vNode.m_sItemFullName); // запоминаем полное имя тэга
wcscpy(vNode.m_sItemFullName, vParentNode.m_sItemName);
wcscat(vNode.m_sItemFullName, TAG_SEPARATOR);
wcscat(vNode.m_sItemFullName, chTemp);
и я стал делать вот так:
std::wstring strTemp;
strTemp.assign(vNode.m_sItemFullName); // запоминаем полное имя strFullID.append(vParentNode.m_sItemName);
strFullID.append(TAG_SEPARATOR);
strFullID.append( strTemp.c_str() );
Делается все одно и тоже, просто во 2-м случае немного утяжеляется. Как лучше все-таки?
Вот скажем такая ситуация. Нужно занести во временную переменную строкового типа данные. А длина заранее неизвестна. Если использовать C-строки, можно объявить массив длиной с гарантией больше возможной длины данных:
TCHAR chTerminalName[128];
if ( wcslen(lpTerminalName) > 0 )
wcscpy(chTerminalName, lpTerminalName);
. При этом переменная будет занимать объем больше, чем могла бы, если скопировано будет фактически немного.
А если делать средствами STL, шаблонный класс сам решит, сколько выделить памяти. Вот это вот смущает.
Профессионалы, пожалуйста, разъясните эти нюансы дилетантам.
Re[2]: вопрос о вариантах использования строк в C++
От:
Аноним
Дата:
20.08.09 07:54
Оценка:
Здравствуйте, agendus, Вы писали:
A>Вот скажем такая ситуация. Нужно занести во временную переменную строкового типа данные. А длина заранее неизвестна. Если использовать C-строки, можно объявить массив длиной с гарантией больше возможной длины данных: A>
A>TCHAR chTerminalName[128];
A> if ( wcslen(lpTerminalName) > 0 )
A> wcscpy(chTerminalName, lpTerminalName);
A>
. При этом переменная будет занимать объем больше, чем могла бы, если скопировано будет фактически немного. A>А если делать средствами STL, шаблонный класс сам решит, сколько выделить памяти. Вот это вот смущает. A>Профессионалы, пожалуйста, разъясните эти нюансы дилетантам.
Что конкретно смущает? что длина std::string будет равна длине C-строки?
Re[2]: вопрос о вариантах использования строк в C++
A>А если делать средствами STL, шаблонный класс сам решит, сколько выделить памяти. Вот это вот смущает. A>Профессионалы, пожалуйста, разъясните эти нюансы дилетантам.
для таких случаев существует reserve(). Тогда resize() ничего не делает пока хватает места.
преимущества -- можно выделять не максимально возможный размер, а разумный предел для 95% случаев, но если все-таки не хватит, то не упадет. объект сам увеличит буфер.
Здравствуйте, agendus, Вы писали:
A>Здравствуйте, уважаемые форумчане. A>Помогите разложить по полочкам и разобраться.
A>Вот есть стандартные C-строки, представляемые как массив char/wchar_t. A>Есть контейнеры в STL для работы со строками, есть класс CString в MFC. A>Можно еще и свой класс-обертку написать.
A>Когда какой вариант лучше использовать?
A>Вот например, пишу я приложение на VC++, без использования MFC. A>Есть классы, поля которых содержат строковые данные. Чтобы не утяжелять класс, это поле определяется типом не std::wstring, а просто LPWSTR.
A>Так вот, сначала такие поля я обрабатывал стандартными функциями C для работы с C-строками. Потом надоело писать каждый раз громоздкие операторы типа A>
A>TCHAR chTemp[MAX_PATH];
A>wcscpy(chTemp, vNode.m_sItemFullName); // запоминаем полное имя тэга
A>wcscpy(vNode.m_sItemFullName, vParentNode.m_sItemName);
A>wcscat(vNode.m_sItemFullName, TAG_SEPARATOR);
A>wcscat(vNode.m_sItemFullName, chTemp);
A>
A>и я стал делать вот так: A>
A>std::wstring strTemp;
A>strTemp.assign(vNode.m_sItemFullName); // запоминаем полное имя strFullID.append(vParentNode.m_sItemName);
A>strFullID.append(TAG_SEPARATOR);
A>strFullID.append( strTemp.c_str() );
A>
A>Делается все одно и тоже, просто во 2-м случае немного утяжеляется. Как лучше все-таки?
Все нижесказанное — ИМХО.
Если есть возможность — использовать CString, или другой удобный/надежный класс строки из какой-нибудь библиотеки.
std::string/wstring использоввать только если недоступен вышеописанный вариант.
С-строки, если уж полная засада, и ничего из вышеперечисленного использовать нельзя.
Любите книгу — источник знаний (с) М.Горький
Re[3]: вопрос о вариантах использования строк в C++
Нет, не это.
В случае использования C-строки смущает, что приходится заботиться о достаточной длине выделяемого массива. А вдруг однажды туда скопируется больше символов, чем отведено? То есть не скопируется, а попытаются — и хоп, ошибка.
В случае std::wstring смущает, что утяжеляется функциональность. Все-таки под класс больше памяти отводится.
Здравствуйте, Аноним, Вы писали:
А>Что конкретно смущает? что длина std::string будет равна длине C-строки?
Re[3]: вопрос о вариантах использования строк в C++
Я знаю о возможностях стандартного объекта. Вопрос был не в этом.
Вопрос в том, где больше "зла":
а) при использовании C-строк (есть риск ошибки при копировании в массив малого размера большой строки — сложно гарантировать невозможность такой ситуации. Но можно грамотно предусмотреть этоот риск)
б) при использовании std::wstring, то есть утяжеление программы за счет использования класса вместо простого массива символов.
Здравствуйте, K13, Вы писали:
A>>А если делать средствами STL, шаблонный класс сам решит, сколько выделить памяти. Вот это вот смущает. A>>Профессионалы, пожалуйста, разъясните эти нюансы дилетантам.
K13>для таких случаев существует reserve(). Тогда resize() ничего не делает пока хватает места. K13>преимущества -- можно выделять не максимально возможный размер, а разумный предел для 95% случаев, но если все-таки не хватит, то не упадет. объект сам увеличит буфер.
Re[4]: вопрос о вариантах использования строк в C++
Здравствуйте, agendus, Вы писали:
A>Нет, не это. A>В случае использования C-строки смущает, что приходится заботиться о достаточной длине выделяемого массива. А вдруг однажды туда скопируется больше символов, чем отведено? То есть не скопируется, а попытаются — и хоп, ошибка. A>В случае std::wstring смущает, что утяжеляется функциональность. Все-таки под класс больше памяти отводится.
Если у тебя не миллионы строк обрабатываются, то увеличение памяти под класс — это фигня, не стоит беспокоиться. А вот нехватка памяти в первом случае может аукнуться часами отладки.
Каждый выбирает по себе (с)
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: вопрос о вариантах использования строк в C++
Вот за это я и зацеплюсь. Почему в ряде предпочтений std::wstring на 2-м месте, а не на 1-м? За счет чего?
Здравствуйте, Bell, Вы писали:
B>Если есть возможность — использовать CString, или другой удобный/надежный класс строки из какой-нибудь библиотеки. B>std::string/wstring использоввать только если недоступен вышеописанный вариант. B>С-строки, если уж полная засада, и ничего из вышеперечисленного использовать нельзя.
Re[4]: вопрос о вариантах использования строк в C++
Здравствуйте, agendus, Вы писали:
A>Я знаю о возможностях стандартного объекта. Вопрос был не в этом. A>Вопрос в том, где больше "зла": A>а) при использовании C-строк (есть риск ошибки при копировании в массив малого размера большой строки — сложно гарантировать невозможность такой ситуации. Но можно грамотно предусмотреть этоот риск) A>б) при использовании std::wstring, то есть утяжеление программы за счет использования класса вместо простого массива символов.
Напишите на контейнерах,померяйте профайлером и если скорость/размер/что-то еще с использованием контейнеров не устраивает — переписывайте на raw строки(заодно будете знать как раз размер под те 95% случаев).
Re[3]: вопрос о вариантах использования строк в C++
Здравствуйте, agendus, Вы писали:
A>Вот за это я и зацеплюсь. Почему в ряде предпочтений std::wstring на 2-м месте, а не на 1-м? За счет чего?
Ну, о неудобстве/некачественности std::string спорили много — попробуй поискать по сайту.
Чем этот класс не нравится мне (из последних ярких впечатлений): новомодные оптимизации для маленьких строк. Из-за этого размер объекта string становится совсем немаленьким. В STLPort эту фичу можно хотя бы отключить... Опять же из-за этой фичи копирование объектов string с помошью memcpy приводит к самым печальным последствиям. Пример: в одном из проектов используется почтовый клиент, стянутный то ли с codeproject, то ли еще откуда-то. Так вот там объекты std::string храняться в MFC-контейнере CSimpleMap, а он при реаллокациях использует memcpy. Мы не будем спорить, насколько это законно с точки зрения стандарта — факт в том, что все это работало до перехода на новую реализацию STL, а пототм случился бабах.
В общем я использую стандартные строки только в крайнем случае, CString мне нравится больше.
Любите книгу — источник знаний (с) М.Горький
Re[2]: вопрос о вариантах использования строк в C++
По использованию памяти. Приложение — сервис, будет работать в режиме 24/7 (постоянно то есть). При запуске может создаваться до нескольких сотен экземпляров класса типа
class COpcNode
{
/// бла-бла...private:
LPWSTR m_sItemName; // или std::wstring - не решил еще
}
Строки будут небольшими — ну может иногда более 256 символов.
Операции со строками — это присвоение значения при создании объекта и переопределение позже.
Никаких MFC/Qt не используется.
Здравствуйте, Chorkov, Вы писали:
C>1) какие требования к производительности / использованию памяти? C>2) каков характерный ожидаемый размер строк? C>3) есть ли информация о специфике строк которые будут хранится? C>( м.б. они ограничены по длине? Часто встречаются одинаковые значения? Как часто встречаются различные операции со строками ) C>4) будет ли процедура тесно привязана к какому либо фреймвокру (MFC/Qt/...)? C>5) предполагается ли предоставление C-like интерфейса для данного класса?
C>В общем случае, ИМХО, std::string/wstring предпочтительнее char[], а больший размер экземпляра класса компенсируется производительностью использования. C>Строки MFC/Qt — использую только если они продиктованы окружением. C>Свои велосипеды и/или char[] — только если профайлер показал проблемы.
Re[3]: вопрос о вариантах использования строк в C++
Здравствуйте, agendus, Вы писали:
A>По использованию памяти. Приложение — сервис, будет работать в режиме 24/7 (постоянно то есть). При запуске может создаваться до нескольких сотен экземпляров класса типа A>
A>class COpcNode
A>{
A> /// бла-бла...
A> private:
A> LPWSTR m_sItemName; // или std::wstring - не решил еще
A>}
A>
A>Строки будут небольшими — ну может иногда более 256 символов.
Строки повторяются? Если да, повторяющиеся строки получены независимо или из одного источника?
До нескольки сотен коротких строк — это мало, чтобы всерьёз думать об оптимизации.
Русский военный корабль идёт ко дну!
Re[4]: вопрос о вариантах использования строк в C++
Строки не повторяются. Ну, глядя на комментарии, делаю выбор в пользу std:wstring.
Здравствуйте, Alexander G, Вы писали:
AG>Здравствуйте, agendus, Вы писали:
A>>По использованию памяти. Приложение — сервис, будет работать в режиме 24/7 (постоянно то есть). При запуске может создаваться до нескольких сотен экземпляров класса типа A>>
A>>class COpcNode
A>>{
A>> /// бла-бла...
A>> private:
A>> LPWSTR m_sItemName; // или std::wstring - не решил еще
A>>}
A>>
A>>Строки будут небольшими — ну может иногда более 256 символов.
AG>Строки повторяются? Если да, повторяющиеся строки получены независимо или из одного источника?
AG>До нескольки сотен коротких строк — это мало, чтобы всерьёз думать об оптимизации.
Re[3]: вопрос о вариантах использования строк в C++
Здравствуйте, agendus, Вы писали:
A>По использованию памяти. Приложение — сервис, будет работать в режиме 24/7 (постоянно то есть). При запуске может создаваться до нескольких сотен экземпляров класса типа A>
A>class COpcNode
A>{
A> /// бла-бла...
A> private:
A> LPWSTR m_sItemName; // или std::wstring - не решил еще
A>}
A>
A>Строки будут небольшими — ну может иногда более 256 символов. A>Операции со строками — это присвоение значения при создании объекта и переопределение позже. A>Никаких MFC/Qt не используется.
Для таких количеств — string/wstring.
Объектов мало, и нет смысла экономить ни на чем.
Re[5]: вопрос о вариантах использования строк в C++
A>class COpcNode
A>{
A> /// бла-бла...
A> private:
A> LPWSTR m_sItemName; // или std::wstring - не решил еще
A>}
A>
OPC сервер ?
У нас OPC сервер работает с более чем 50000 тегов в режиме 24/7 и использует CString только потому, что изначально писался на MFC и там есть встроенная функция AllocSystemString() (или как-то так), сейчас переходим на std::wstring и разницы не ощущаем.
Re[2]: вопрос о вариантах использования строк в C++
Alexander G пишет:
> NULL-termianted — зло. И с т.з. корректонсти (обеспечение правильного
Чушь собачья.
> A>Когда какой вариант лучше использовать? > > CString.
Я хочу напомнить, или сообщить, если кто не знает, что Microsoft-овский CString
теперь отделён от MFC и ATL и даже сделан free в каком-то виде, правда не
знаю, в каком, ибо входит в состав free-шного WTL.
Posted via RSDN NNTP Server 2.1 beta
Re[5]: вопрос о вариантах использования строк в C++
Здравствуйте, MasterZiv, Вы писали:
MZ>agendus пишет:
>> В случае std::wstring смущает, что утяжеляется функциональность. >> Все-таки под класс больше памяти отводится.
MZ>Просто не думай об этом. MZ>На самом деле "под класс (wstring) больше памяти отводится" -- MZ>просто неправда.
Вот оно оказывается как, а мужики-то и не знают!
Пример:
MSVC 7.1, DinkumSTL: sizeof(std::string) == 28, sizeof(std::wstring) == 28.
STLPort 5.1 sizeof(std::string) == 24, sizeof(std::wstring) == 40.
В STLPort хотя бы можно отключить эту фичу...
MZ>В некоторых случаях ты память даже будещь экономить.
Ключевое слово — в некоторых.
Хотя, безусловно, в приведенном авторе случае все это несущественно.