Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
[c++] сравнение std::string == const std::string vs std::string == lpctstr 17.10.07 07:41
Автор: void <Grebnev Valery> Статус: Elderman Отредактировано 17.10.07 07:49 Количество правок: 2
|
В проекте есть большое число сравнений строк (STL имплементации Microsoft VC++8.0):
const std::string s1(_T("some string1"));
const std::string s2(_T("some string2"));
...
void f()
{
std::string value;
...
if( value == s1) {
...
} else if ( value == s2) {
...
}
...
}
На мой вопрос, почему в качестве констант для сравнения используются const std::string, а не const LPCTSTR, местные специалисты объяснили, что всё дело в перформанс. Типа, в случае const std::string s1, конструктор s1 будет вызван только один раз (при инициализации всех статических объектов), а вот в случае (как я предлагал) использования const LPCTSTR для неё будет автоматически создаваться (STL-ем) временный std::string объект, который и будет потом сравниваться с value. Т.е. в коде ниже, в блоке if(...), каждый раз будет создаваться временный std::string(s3):
const LPCTSTR s3 = _T("some string3");
void f()
{
std::string value;
...
if( value == s3) {
...
Посмотрев имлементациию оператора operator== :
template<class _Elem,
class _Traits,
class _Alloc> inline
bool __CLRCALL_OR_CDECL operator==(
const basic_string<_Elem, _Traits, _Alloc>& _Left,
const _Elem *_Right)
{ // test for string vs. NTCS equality
return (_Left.compare(_Right) == 0);
}
я не смог обнаружить создания какого либо временного объекта, равно как и в имплементации basic_string::compare(const _Elem *_Right):
int __CLR_OR_THIS_CALL compare(const _Elem *_Ptr) const
{ // compare [0, _Mysize) with [_Ptr, <null>)
return (compare(0, _Mysize, _Ptr, _Traits::length(_Ptr)));
}
Я чего-то не допонимаю специалистов. Покажите мне пальцем, пожалуйста, гдеж этот временный объект-то создаётся? Думаю, ошибочка у специалистов вышла, а я -то говорю всё правильно - никакого временного объекта вовсе и не создаётся, и не нужно использовать
const std::string s1(_T("some string1"));
а нужно использовать
const LPCTSTR s1 = _T("some string1");
поскольку так будет проще и быстрее. Правильно я говорю?
И последний вопрос: "compare", насколько я понимаю, использует посимвольное сравнение. Может вообще заменить это на strcmp?
Спасибо.
|
|
[C++] после нехитрого дебага специалисты были убеждены в их неправоте. 18.10.07 04:29
Автор: void <Grebnev Valery> Статус: Elderman Отредактировано 18.10.07 04:53 Количество правок: 1
|
Кстати, появились причины не менять код - если менять, то надо перелопачивать там тонны кода. Решил оставить как есть.
Спасибо всем.
|
|
Специалисты выросли на Borland. Борландрвскмй AnsiString не... 17.10.07 12:11
Автор: Killer{R} <Dmitry> Статус: Elderman
|
Специалисты выросли на Borland. Борландрвскмй AnsiString не имеет оператора == сравнивающего с const char * и потому при сравнении создается временный AnsiString. std::string же имеет оператор сравнения с const char * и врядли какаято даже самая тупая имплементация STL будет в этом операторе создавать временный объект.
Но вообще говоря сравнение std::string с std::string быстрее чем std::string с const char * потому что во втором случае приходится еще определять длину строки, или же в процессе проверять еще каждый сравниваемый символ с нулем.
|
| |
Верно. Хорошее замечание. 18.10.07 04:38
Автор: void <Grebnev Valery> Статус: Elderman
|
|
|
[c++] чепушина какая-то! lpctstr просто указатель 17.10.07 11:55
Автор: Zef <Alloo Zef> Статус: Elderman
|
Если мы будем вызывать метод класса по указателю, то никаких конструкторов вызываться не будет, даже, если нужно. Просто, если мы попытаемся обратиться к не инициализированному объекту будет ошибка. Впрочем, если конструктор не вызывали, то и указатель будет пустой.
|
| |
Не совсет так (см замечание автора выше по нитке). Если бы... 18.10.07 04:46
Автор: void <Grebnev Valery> Статус: Elderman
|
> Если мы будем вызывать метод класса по указателю, то > никаких конструкторов вызываться не будет, даже, если > нужно. Просто, если мы попытаемся обратиться к не > инициализированному объекту будет ошибка. Впрочем, если > конструктор не вызывали, то и указатель будет пустой.
Не совсет так (см замечание автора выше по нитке). Если бы не было бы определено операторов: bool operator== ( const char* lhs, const string& rhs ); bool operator== ( const string& lhs, const char* rhs );, а был бы только оператор bool operator== ( const string& lhs, const string& rhs ); (что по некоторой инфе и было на заре STL):, то конструктор (string ( const char * s );) вызывался бы автоматически, создавая дополнительные оверхеды.
|
|
Специалисты однозначно не правы 17.10.07 08:47
Автор: Heller <Heller> Статус: Elderman
|
> поскольку так будет проще и быстрее. Правильно я говорю? > > И последний вопрос: "compare", насколько я понимаю, > использует посимвольное сравнение. Может вообще заменить > это на strcmp?
Я не знаю достоверно, но вообще такие моменты вполне по силам взять на себя оптимизатору - надо проверять. В любом случае выигрыш вряд ли будет большим (если только ты не делаешь несколько сотен/тысяч таких сравнений в секунду).
|
| |
Там делается при старте программы ~440000*50 сравнений... 18.10.07 04:50
Автор: void <Grebnev Valery> Статус: Elderman
|
> > поскольку так будет проще и быстрее. Правильно я > говорю? > > > > И последний вопрос: "compare", насколько я понимаю, > > использует посимвольное сравнение. Может вообще > заменить > > это на strcmp? > > Я не знаю достоверно, но вообще такие моменты вполне по > силам взять на себя оптимизатору - надо проверять. В любом > случае выигрыш вряд ли будет большим (если только ты не > делаешь несколько сотен/тысяч таких сравнений в секунду). Там делается при старте программы ~440000*50 сравнений. 440000 -число вызовов функции сравнения. 50 - число if()else if()else if в этой функции.
|
|
|