Оптимизация String параметра
От: Kluev  
Дата: 12.10.04 10:01
Оценка: 20 (1)
У меня есть свой класс строки с подсчетом ссылок. И вот иногда сидишь и думаешь как передавать строку в функцию?

void f(const char *str);
или
void f(const String &str );


Вообщем то и то другое далеко от идеала.
В первом случае если строка в функции "запоминается" теряется преимущество подсчета ссылок, а во втором строка может только юзатся на чтение, и создание временного обьекта String (malloc + memcpy) не оправданно.

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

void f(StrBox str);


Сам StrBox + фрагменты кода из String:

    template <class T>
        class StrBox_
    {
    public:
        const T        *cstr;
        const bool    smart;

    public:
        StrBox_( const T *str ) : cstr(str), smart(false) {}
        StrBox_( const String_<T> &str ) : cstr(str), smart(true) {}
        StrBox_( const T *str, bool smart ) : cstr(str), smart(smart) {}
        StrBox_( const StrBox_ &sbx ) : cstr(sbx.cstr), smart(sbx.smart) {}

    public:
        operator const T* () const { return cstr; }
    };
// конструктор и присваивание строки, если возможно юзается addref в противном случае copy:
    template <class T>
        String_<T>::String_( const StrBox_<T> &sbx )
    {
        if ( sbx.smart )
            s_ = string_ref( (T*)sbx.cstr );
        else
            s_ = alloc_( sbx.cstr, str_len(sbx.cstr) );
    }

    template <class T> String_<T>&
        String_<T>::operator = ( const StrBox_<T> &sbx )
    {
        if ( sbx.smart )
            return reset_( string_ref( (T*)s.cstr ) );
        else
            return reset_(alloc_(sbx.cstr, str_len(sbx.cstr)));
    }


P.S. Счастливые обладатели собственных string-велосипедов с подсчетом ссылок, могут заюзать и извлечь пользу. Для std::string такое не сделать.
Re: Оптимизация String параметра
От: AndrewJD США  
Дата: 12.10.04 10:25
Оценка:
Здравствуйте, Kluev, Вы писали:

K>У меня есть свой класс строки с подсчетом ссылок. И вот иногда сидишь и думаешь как передавать строку в функцию?


K>
K>void f(const char *str);
K>или
K>void f(const String &str );
K>


K>Вообщем то и то другое далеко от идеала.

K>В первом случае если строка в функции "запоминается" теряется преимущество подсчета ссылок, а во втором строка может только юзатся на чтение, и создание временного обьекта String (malloc + memcpy) не оправданно.

Я может чего не понимаю, но чем плоха обычная передача ?

void f(String str);
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Re: Оптимизация String параметра
От: MaximE Великобритания  
Дата: 12.10.04 10:25
Оценка:
Kluev wrote:

> У меня есть свой класс строки с подсчетом ссылок. И вот иногда сидишь и думаешь как передавать строку в функцию?

>
>
> void f(const char *str);
> или
> void f(const String &str );
>

>
> Вообщем то и то другое далеко от идеала.
> В первом случае если строка в функции "запоминается" теряется преимущество подсчета ссылок, а во втором строка может только юзатся на чтение, и создание временного обьекта String (malloc + memcpy) не оправданно.

[]

> P.S. Счастливые обладатели собственных string-велосипедов с подсчетом ссылок, могут заюзать и извлечь пользу. Для std::string такое не сделать.


Можешь воспользоваться константной строкой, которая поддерживает reference semantics: http://conststring.sourceforge.net/

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9 gamma
Re[2]: Оптимизация String параметра
От: Kluev  
Дата: 12.10.04 10:39
Оценка:
Здравствуйте, AndrewJD, Вы писали:

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


AJD>Я может чего не понимаю, но чем плоха обычная передача ?


AJD>
AJD>void f(String str);
AJD>


тем что когда пишем f("zzzzz") или f(str), где str — const char*
будет создан временный обьект стринг, а это как правило malloc+strlen+memcpy. А когда это еще произходит и в цикле то имеем неслабый оверхед. К примеру грузится что-то из хмл:

// вызывается в цикле
void Item::load( XmlNode &n )
{
   this->val = n.attrib_int("Val"); // вот здесь оверхед на создание стринг
   this->s   = n.attrib_str("Zzz"); // и здес тоже
}
Re[3]: Оптимизация String параметра
От: AndrewJD США  
Дата: 12.10.04 17:17
Оценка:
Здравствуйте, Kluev, Вы писали:

Все равно не понял.

K>тем что когда пишем f("zzzzz") или f(str), где str — const char*

K>будет создан временный обьект стринг, а это как правило malloc+strlen+memcpy. А когда это еще произходит и в цикле то имеем неслабый оверхед. К примеру грузится что-то из хмл:

K>
K>// вызывается в цикле
K>void Item::load( XmlNode &n )
K>{
   this->>val = n.attrib_int("Val"); // вот здесь оверхед на создание стринг
   this->>s   = n.attrib_str("Zzz"); // и здес тоже
K>}
K>


Если мы захотим внутри attrib_int работать со строкой, нам все равно необходимо создать String из StrBox. Так какая разница, когда будет создан этот новый стринг ?
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Re: Оптимизация String параметра
От: AdUser  
Дата: 12.10.04 18:17
Оценка:
Может быть, поле, хранящее число ссылок, объявить с модификатором mutable?
Тогда его значение можно будет менять, не взирая на const
Re[4]: Оптимизация String параметра
От: Kluev  
Дата: 13.10.04 07:30
Оценка: 2 (1)
Здравствуйте, AndrewJD, Вы писали:

K>>
K>>// вызывается в цикле
K>>void Item::load( XmlNode &n )
K>>{
   this->val = n.attrib_int("Val"); // вот здесь оверхед на создание стринг
   this->s   = n.attrib_str("Zzz"); // и здес тоже
K>>}
K>>


AJD>Если мы захотим внутри attrib_int работать со строкой, нам все равно необходимо создать String из StrBox. Так какая разница, когда будет создан этот новый стринг ?


А если не захотим? А в данном пример 100% не захотим. Т.к. attrib_int не будет модифицировать строку, а использует ее как ключ для поиска в map-e. hash-e и т.п.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.