Using QString Effectively/bg: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
No edit summary
Line 3: Line 3:
'''Български''' [[UsingQStringEffectively|English]] [[UsingQStringEffectively SimplifiedChinese|简体中文]]
'''Български''' [[UsingQStringEffectively|English]] [[UsingQStringEffectively SimplifiedChinese|简体中文]]


[toc align_right="yes" depth="1"]
[toc align_right="yes" depth="1"]


Написано от: Girish Ramakrishnan, ForwardBias Technologies
Написано от: Girish Ramakrishnan, ForwardBias Technologies
Line 9: Line 9:
Тази статия обяснява предназначението на различните класове свързани с ''QString''.
Тази статия обяснява предназначението на различните класове свързани с ''QString''.


= QLatin1String : Избягване на скрито заделяне на памет в оператора "==" =
= QLatin1String : Избягване на скрито заделяне на памет в оператора "==" =


Създаването на QString от ''char'' масив може да предизвика заделяне на памет. Пример:<br /><code><br /> if (fruit == &quot;apple&amp;quot;) { … } // вероятно заделяне на памет<br /></code>
Създаването на QString от ''char'' масив може да предизвика заделяне на памет. Пример:
<code>
if (fruit == "apple") { … } // вероятно заделяне на памет
</code>


QString предоставя QString::operator==(const char *) за сравняване със C-стрингове. Както е обяснено в &quot;QtString&amp;quot;:http://developer.qt.nokia.com/wiki/QtStrings/, кодировката на C-стринговете се определя като се използва QTextCodec::setCodecForCStrings(). Когато не е сложено специално кодиране, Qt изпълнява горното сравнение като предоставя специализирана функция, която сравнява Уникод стринга (fruit) и Latin-1 стринга ('apple'). Това сравнение е бързо и не изисква заделяне на памет.
QString предоставя QString::operator==(const char *) за сравняване със C-стрингове. Както е обяснено в "QtString":http://developer.qt.nokia.com/wiki/QtStrings/, кодировката на C-стринговете се определя като се използва QTextCodec::setCodecForCStrings(). Когато не е сложено специално кодиране, Qt изпълнява горното сравнение като предоставя специализирана функция, която сравнява Уникод стринга (fruit) и Latin-1 стринга ('apple'). Това сравнение е бързо и не изисква заделяне на памет.


Обаче, когато QTextCodec::setCodecForCString е нагласен, &quot;apple&amp;quot; се конвертира в QString като се използва QString::fromAscii(). Това означава, че QString ще задели памет за стринга &quot;apple&amp;quot; и ще създаде копие на C масива преди да изпълни сравнението!
Обаче, когато QTextCodec::setCodecForCString е нагласен, "apple" се конвертира в QString като се използва QString::fromAscii(). Това означава, че QString ще задели памет за стринга "apple" и ще създаде копие на C масива преди да изпълни сравнението!


Разработчиците на приложения нагласяват QTextCodec::setCodecForCString() в main() без да осъзнават, че това има страничен ефект и причинява заделяне на памет за всеки един C-стринг при сравнение.
Разработчиците на приложения нагласяват QTextCodec::setCodecForCString() в main() без да осъзнават, че това има страничен ефект и причинява заделяне на памет за всеки един C-стринг при сравнение.


Тъй като сравняването с Latin-1 C-стрингове е често срещано в програмите, Qt предоставя специален клас, наречен QLatin1String, който просто съдържа указател към C-стринг с Latin-1 кодировка. В допълнение, QString предоставя и оператора QString::operator(const QLatin1String &amp;amp;), който извиква специална функция, която сравнява Уникод стринг и Latin1 стринг. Можем да направим горният код без съмнение по-бърз като напишем:
Тъй като сравняването с Latin-1 C-стрингове е често срещано в програмите, Qt предоставя специален клас, наречен QLatin1String, който просто съдържа указател към C-стринг с Latin-1 кодировка. В допълнение, QString предоставя и оператора QString::operator(const QLatin1String &amp;amp;), който извиква специална функция, която сравнява Уникод стринг и Latin1 стринг. Можем да направим горният код без съмнение по-бърз като напишем:
&lt;code&gt;
<code>
     if (fruit QLatin1String(&quot;apple&amp;quot;)) { … } // бърз и оказва кодировката<br /></code>
     if (fruit QLatin1String("apple")) { … } // бърз и оказва кодировката
</code>


В кода на Qt, всички сравнения със C-стрингове използват QLatin1String, тъй като приложението може да избере произволен кодек за C-стринговете си.
В кода на Qt, всички сравнения със C-стрингове използват QLatin1String, тъй като приложението може да избере произволен кодек за C-стринговете си.
Line 35: Line 39:
= QStringBuilder : Бързо обединяване на QString-ове =
= QStringBuilder : Бързо обединяване на QString-ове =


Кода по-долу изисква поне 2 заделяния на памет. Първото заделяне е за да се съхрани резултата от &quot;(&quot; + type. И след това има още едно заради добавянето на &quot;)&quot;. Броят на заделянията се увеличава при всяко следващото извикване на оператора &quot;''&quot;.<br /><code><br /> if (foo.startsWith(&quot;(&quot;'' type + &quot;)&quot;))<br /></code>
Кода по-долу изисква поне 2 заделяния на памет. Първото заделяне е за да се съхрани резултата от "(" + type. И след това има още едно заради добавянето на ")". Броят на заделянията се увеличава при всяко следващото извикване на оператора "''".
<code>
if (foo.startsWith("("'' type + ")"))
</code>


Допълнителните заделяния на памет могат да бъдат избегнати ако дължината на крайният QString се знае предварително. Qt 4.6 въведе вътрешния клас QStringBuilder, който &quot;резервира&amp;quot; памет за събирането на един път. Той постига това като при всяко използване на оператора + по-горе се връща различена клас (не QString). Този клас следи какви стрингове се добавят и колко памет е нужна за тях на всяка стъпка. На края, когато операцията по обединяването се конвертира обратно в QString, класа заделя памет и копира всички стрингове един след друг. Тази възможност може да бъде включена като се използва QT_USE_FAST_CONCATENATION. Когато това е дефинирано, можете да използвате оператора '' вместо ''''. Пример:<br /><code><br /> if (foo.startsWith(&quot;(&quot; % type % &quot;)&quot;))<br /></code>
Допълнителните заделяния на памет могат да бъдат избегнати ако дължината на крайният QString се знае предварително. Qt 4.6 въведе вътрешния клас QStringBuilder, който "резервира" памет за събирането на един път. Той постига това като при всяко използване на оператора + по-горе се връща различена клас (не QString). Този клас следи какви стрингове се добавят и колко памет е нужна за тях на всяка стъпка. На края, когато операцията по обединяването се конвертира обратно в QString, класа заделя памет и копира всички стрингове един след друг. Тази възможност може да бъде включена като се използва QT_USE_FAST_CONCATENATION. Когато това е дефинирано, можете да използвате оператора '' вместо ''''. Пример:
<br />'''' може да се използва вместо '' като се дефинира QT_USE_FAST_OPERATOR_PLUS. Вижте &quot;Fast concatenation&amp;quot;:http://doc.qt.nokia.com/4.6/qstring.html#more-efficient-string-construction за повече детайли
<code>
if (foo.startsWith("(" % type % ")"))
</code>
 
'''' може да се използва вместо '' като се дефинира QT_USE_FAST_OPERATOR_PLUS. Вижте "Fast concatenation":http://doc.qt.nokia.com/4.6/qstring.html#more-efficient-string-construction за повече детайли


= QStringMatcher : Бързо търсена на стринг в стринг =
= QStringMatcher : Бързо търсена на стринг в стринг =


QStringMatcher може да се използва за търсене на стринг многократно в множество стрингове и в един стринг много пъти. Класът използва &quot;алгоритъма на Бойър-Муур&amp;quot;:http://en.wikipedia.org/wiki/Boyer–Moore_string_search_algorithm за да извърши бързо търсене.
QStringMatcher може да се използва за търсене на стринг многократно в множество стрингове и в един стринг много пъти. Класът използва "алгоритъма на Бойър-Муур":http://en.wikipedia.org/wiki/Boyer–Moore_string_search_algorithm за да извърши бързо търсене.

Revision as of 12:46, 25 February 2015


Български English 简体中文

[toc align_right="yes" depth="1"]

Написано от: Girish Ramakrishnan, ForwardBias Technologies

Тази статия обяснява предназначението на различните класове свързани с QString.

QLatin1String : Избягване на скрито заделяне на памет в оператора "=="

Създаването на QString от char масив може да предизвика заделяне на памет. Пример:

 if (fruit == "apple") {  } // вероятно заделяне на памет

QString предоставя QString::operator==(const char *) за сравняване със C-стрингове. Както е обяснено в "QtString":http://developer.qt.nokia.com/wiki/QtStrings/, кодировката на C-стринговете се определя като се използва QTextCodec::setCodecForCStrings(). Когато не е сложено специално кодиране, Qt изпълнява горното сравнение като предоставя специализирана функция, която сравнява Уникод стринга (fruit) и Latin-1 стринга ('apple'). Това сравнение е бързо и не изисква заделяне на памет.

Обаче, когато QTextCodec::setCodecForCString е нагласен, "apple" се конвертира в QString като се използва QString::fromAscii(). Това означава, че QString ще задели памет за стринга "apple" и ще създаде копие на C масива преди да изпълни сравнението!

Разработчиците на приложения нагласяват QTextCodec::setCodecForCString() в main() без да осъзнават, че това има страничен ефект и причинява заделяне на памет за всеки един C-стринг при сравнение.

Тъй като сравняването с Latin-1 C-стрингове е често срещано в програмите, Qt предоставя специален клас, наречен QLatin1String, който просто съдържа указател към C-стринг с Latin-1 кодировка. В допълнение, QString предоставя и оператора QString::operator(const QLatin1String &amp;), който извиква специална функция, която сравнява Уникод стринг и Latin1 стринг. Можем да направим горният код без съмнение по-бърз като напишем:

    if (fruit QLatin1String("apple")) {  } // бърз и оказва кодировката

В кода на Qt, всички сравнения със C-стрингове използват QLatin1String, тъй като приложението може да избере произволен кодек за C-стринговете си.

QStringRef : Обработка на стрингове без заделяне на памет

QString има множество методи за обработка на стрингове като mid(), left(), right(). Всички те създават нов QString и следователно заделя и копират данни от съществуващия QString. Вместо това могат да се използват QString::midRef(), QString::leftRef() и QString::rightRef(), за да се получи QStringRef. QStringRef е връзка към част от QString. QString също предоставя много предефинирани операции като QString::operator==(const QStringRef &) за оптимална употреба с QStringRef.

QString::reserve и QString::squeeze

По-добре е да заделите повече памет предварително с QString::reserve, така че всяко извикване на QString::append() да не причинява ново заделяне. Допълнителната памет може да освободи по-късно с QString::squeeze.

QStringBuilder : Бързо обединяване на QString-ове

Кода по-долу изисква поне 2 заделяния на памет. Първото заделяне е за да се съхрани резултата от "(" + type. И след това има още едно заради добавянето на ")". Броят на заделянията се увеличава при всяко следващото извикване на оператора "".

 if (foo.startsWith("("'' type + ")"))

Допълнителните заделяния на памет могат да бъдат избегнати ако дължината на крайният QString се знае предварително. Qt 4.6 въведе вътрешния клас QStringBuilder, който "резервира" памет за събирането на един път. Той постига това като при всяко използване на оператора + по-горе се връща различена клас (не QString). Този клас следи какви стрингове се добавят и колко памет е нужна за тях на всяка стъпка. На края, когато операцията по обединяването се конвертира обратно в QString, класа заделя памет и копира всички стрингове един след друг. Тази възможност може да бъде включена като се използва QT_USE_FAST_CONCATENATION. Когато това е дефинирано, можете да използвате оператора вместо ''. Пример:

 if (foo.startsWith("(" % type % ")"))

'' може да се използва вместо като се дефинира QT_USE_FAST_OPERATOR_PLUS. Вижте "Fast concatenation":http://doc.qt.nokia.com/4.6/qstring.html#more-efficient-string-construction за повече детайли

QStringMatcher : Бързо търсена на стринг в стринг

QStringMatcher може да се използва за търсене на стринг многократно в множество стрингове и в един стринг много пъти. Класът използва "алгоритъма на Бойър-Муур":http://en.wikipedia.org/wiki/Boyer–Moore_string_search_algorithm за да извърши бързо търсене.