[graphics/krita] /: Avoid using toLower() for of canse-insensitive comparison
Dmitry Kazakov
null at kde.org
Mon Oct 26 16:58:51 GMT 2026
Git commit fbd5e1f712bacc941736353a1a665012973858c8 by Dmitry Kazakov.
Committed on 26/10/2026 at 16:54.
Pushed by dkazakov into branch 'master'.
Avoid using toLower() for of canse-insensitive comparison
toLower() allocates heap memory, which is extremely
slow on Windows, so we should avoid doing that in hot
loops.
CC:kimageshop at kde.org
M +9 -0 HACKING
M +2 -2 libs/flake/text/KoFFWWSConverter.cpp
M +9 -9 libs/flake/text/KoSvgTextContentElement.cpp
M +3 -3 libs/flake/text/KoSvgTextProperties.cpp
M +6 -6 libs/pigment/KoColor.cpp
M +1 -1 libs/resources/KisResourceModel.cpp
M +3 -3 libs/resources/KisTagModel.cpp
M +1 -1 libs/resources/KisTagResourceModel.cpp
https://invent.kde.org/graphics/krita/-/commit/fbd5e1f712bacc941736353a1a665012973858c8
diff --git a/HACKING b/HACKING
index ccca6137f89..1aa2997d181 100644
--- a/HACKING
+++ b/HACKING
@@ -388,6 +388,15 @@ On menu action names: "Group layers" vs "Group layer(s)"
i18ncp("@action:inmenu", "Group layer", "Group layers")
+Case insensitive string comparison
+
+ Instead of using `str.toLower() == "abc"` prefer using
+ `str.compare("abc", Qt::CaseInsensitive) == 0`, especially in hot
+ places
+
+ The `QString::toLower()` call is expensive on Winodws, since it allocates
+ memory on heap. It is more efficient to perform the comparison in place.
+
With Krita now supporting Python scripting, we need guidelines for these as well.
These guidelines are preliminary and may be further refined in the future.
diff --git a/libs/flake/text/KoFFWWSConverter.cpp b/libs/flake/text/KoFFWWSConverter.cpp
index f6948113734..f95997a45db 100644
--- a/libs/flake/text/KoFFWWSConverter.cpp
+++ b/libs/flake/text/KoFFWWSConverter.cpp
@@ -146,7 +146,7 @@ struct FontFamilyNode {
static FontFamilyNode createWWSFamilyNode(const FontFamilyNode &child, const FontFamilyNode &typographic, QStringList existingWWSNames) {
FontFamilyNode wwsFamily;
if (child.type != KoSvgText::OpenTypeFontType) {
- if (child.fontStyle.toLower() == "regular") {
+ if (child.fontStyle.compare("regular", Qt::CaseInsensitive) == 0) {
wwsFamily.fontFamily = child.fontFamily;
} else {
wwsFamily.fontFamily = child.fontFamily + " " + child.fontStyle;
@@ -763,7 +763,7 @@ void KoFFWWSConverter::sortIntoWWSFamilies()
// Like, it is technically correct, because it allows us to select fonts with CSS
// that would otherwise be unselectable, but this does mean that other applications
// would need to have our exact idea of a CSS family name.
- if (wws->fontStyle.toLower() != "regular"
+ if (wws->fontStyle.compare("regular", Qt::CaseInsensitive) != 0
&& !font->fontStyle.contains(wws->fontStyle)) {
continue;
}
diff --git a/libs/flake/text/KoSvgTextContentElement.cpp b/libs/flake/text/KoSvgTextContentElement.cpp
index 741169dae10..93d0c88741d 100644
--- a/libs/flake/text/KoSvgTextContentElement.cpp
+++ b/libs/flake/text/KoSvgTextContentElement.cpp
@@ -157,8 +157,8 @@ KoSvgTextProperties adjustPropertiesForFontSizeWorkaround(const KoSvgTextPropert
}
-const QString TEXT_STYLE_TYPE = "krita:style-type";
-const QString TEXT_STYLE_RES = "krita:style-resolution";
+const QLatin1String TEXT_STYLE_TYPE("krita:style-type");
+const QLatin1String TEXT_STYLE_RES("krita:style-resolution");
bool KoSvgTextContentElement::loadSvg(const QDomElement &e, SvgLoadingContext &context, bool rootNode)
{
@@ -232,11 +232,11 @@ bool KoSvgTextContentElement::loadSvg(const QDomElement &e, SvgLoadingContext &c
}
}
- if (e.hasAttribute(TEXT_STYLE_TYPE.toLatin1().data())) {
- properties.setProperty(KoSvgTextProperties::KraTextStyleType, e.attribute(TEXT_STYLE_TYPE.toLatin1().data()));
- if (e.hasAttribute(TEXT_STYLE_RES.toLatin1().data())) {
- QString resolution = e.attribute(TEXT_STYLE_RES.toLatin1().data()).toLower();
- if (resolution.endsWith("dpi")) {
+ if (e.hasAttribute(TEXT_STYLE_TYPE)) {
+ properties.setProperty(KoSvgTextProperties::KraTextStyleType, e.attribute(TEXT_STYLE_TYPE));
+ if (e.hasAttribute(TEXT_STYLE_RES)) {
+ QString resolution = e.attribute(TEXT_STYLE_RES);
+ if (resolution.endsWith("dpi", Qt::CaseInsensitive)) {
resolution.chop(3);
}
properties.setProperty(KoSvgTextProperties::KraTextStyleResolution, KisDomUtils::toInt(resolution));
@@ -367,9 +367,9 @@ bool KoSvgTextContentElement::saveSvg(SvgSavingContext &context,
}
if (properties.hasProperty(KoSvgTextProperties::KraTextStyleType)) {
- context.shapeWriter().addAttribute(TEXT_STYLE_TYPE.toLatin1().data(), properties.property(KoSvgTextProperties::KraTextStyleType).toString());
+ context.shapeWriter().addAttribute(TEXT_STYLE_TYPE.data(), properties.property(KoSvgTextProperties::KraTextStyleType).toString());
if (properties.hasProperty(KoSvgTextProperties::KraTextStyleResolution)) {
- context.shapeWriter().addAttribute(TEXT_STYLE_RES.toLatin1().data(), QString::number(properties.property(KoSvgTextProperties::KraTextStyleResolution).toInt())+"dpi");
+ context.shapeWriter().addAttribute(TEXT_STYLE_RES.data(), QString::number(properties.property(KoSvgTextProperties::KraTextStyleResolution).toInt())+"dpi");
}
}
diff --git a/libs/flake/text/KoSvgTextProperties.cpp b/libs/flake/text/KoSvgTextProperties.cpp
index b442a6d422c..1d81ae828e0 100644
--- a/libs/flake/text/KoSvgTextProperties.cpp
+++ b/libs/flake/text/KoSvgTextProperties.cpp
@@ -306,10 +306,10 @@ QVariantMap parseFeatureSettingsStringList(const QStringList features) {
} else {
bool ok = false;
int featureVal = tag.second.toInt(&ok);
- if (tag.second.toLower() == "on") {
+ if (tag.second.compare("on", Qt::CaseInsensitive) == 0) {
featureVal = 1;
ok = true;
- } else if (tag.second.toLower() == "off") {
+ } else if (tag.second.compare("off", Qt::CaseInsensitive) == 0) {
featureVal = 0;
ok = true;
}
@@ -335,7 +335,7 @@ void KoSvgTextProperties::parseSvgTextAttribute(const SvgLoadingContext &context
<< "0deg"
<< "90"
<< "90deg";
- if (acceptedOrientations.contains(value.toLower())) {
+ if (acceptedOrientations.contains(value, Qt::CaseInsensitive)) {
if (!autoValue.isAuto) {
autoValue.customValue = kisRadiansToDegrees(roundToStraightAngle(autoValue.customValue));
}
diff --git a/libs/pigment/KoColor.cpp b/libs/pigment/KoColor.cpp
index c75970d0ff6..b53e396e81a 100644
--- a/libs/pigment/KoColor.cpp
+++ b/libs/pigment/KoColor.cpp
@@ -456,9 +456,9 @@ KoColor KoColor::fromXML(const QString &xml)
QString channelDepthID = root.attribute("channeldepth", Integer16BitsColorDepthID.id());
bool ok;
- if (child.hasAttribute("space") || child.tagName().toLower() == "srgb") {
+ if (child.hasAttribute("space") || child.tagName().compare("srgb", Qt::CaseInsensitive) == 0) {
c = KoColor::fromXML(child, channelDepthID, &ok);
- } else if (root.hasAttribute("space") || root.tagName().toLower() == "srgb"){
+ } else if (root.hasAttribute("space") || root.tagName().compare("srgb", Qt::CaseInsensitive) == 0){
c = KoColor::fromXML(root, channelDepthID, &ok);
} else {
qWarning() << "Cannot parse color from xml" << xml;
@@ -532,7 +532,7 @@ KoColor KoColor::fromSVG11(const QString value, QHash<QString, const KoColorProf
KoColor parsed(KoColorSpaceRegistry::instance()->rgb16(KoColorSpaceRegistry::instance()->p709SRGBProfile()));
parsed.setOpacity(1.0);
- if (value.toLower() == "none") {
+ if (value.compare("none", Qt::CaseInsensitive) == 0) {
return parsed;
}
@@ -559,7 +559,7 @@ KoColor KoColor::fromSVG11(const QString value, QHash<QString, const KoColorProf
dbgPigment << "Color definitions found during svg11parsing" << colorDefinitions;
for (QString def : colorDefinitions) {
- if (def.toLower() == "currentcolor") {
+ if (def.compare("currentcolor", Qt::CaseInsensitive) == 0) {
parsed = current;
#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
} else if (QColor::isValidColor(def)) {
@@ -567,7 +567,7 @@ KoColor KoColor::fromSVG11(const QString value, QHash<QString, const KoColorProf
} else if (QColor::isValidColorName(def)) {
#endif
parsed.fromQColor(QColor(def));
- } else if (def.toLower().startsWith("rgb")) {
+ } else if (def.startsWith("rgb", Qt::CaseInsensitive)) {
QString parse = def.trimmed();
QStringList colors = parse.split(',');
QString r = colors[0].right((colors[0].length() - 4)).trimmed();
@@ -590,7 +590,7 @@ KoColor KoColor::fromSVG11(const QString value, QHash<QString, const KoColorProf
}
parsed.fromQColor(QColor(r.toInt(), g.toInt(), b.toInt()));
- } else if (def.toLower().startsWith("icc-color")) {
+ } else if (def.startsWith("icc-color", Qt::CaseInsensitive)) {
QStringList values = def.split(",");
QString iccprofilename = values.first().split("(").last();
values.removeFirst();
diff --git a/libs/resources/KisResourceModel.cpp b/libs/resources/KisResourceModel.cpp
index 9f15fa61646..71e2ec49979 100644
--- a/libs/resources/KisResourceModel.cpp
+++ b/libs/resources/KisResourceModel.cpp
@@ -1113,7 +1113,7 @@ bool KisResourceModel::lessThan(const QModelIndex &source_left, const QModelInde
QString nameLeft = sourceModel()->data(source_left, Qt::UserRole + KisAbstractResourceModel::Name).toString();
QString nameRight = sourceModel()->data(source_right, Qt::UserRole + KisAbstractResourceModel::Name).toString();
- return nameLeft.toLower() < nameRight.toLower();
+ return nameLeft.compare(nameRight, Qt::CaseInsensitive) < 0;
}
QVector<KoResourceSP> KisResourceModel::filterByColumn(const QString filter, KisAbstractResourceModel::Columns column) const
diff --git a/libs/resources/KisTagModel.cpp b/libs/resources/KisTagModel.cpp
index 2df9bc0a34e..f310fa44390 100644
--- a/libs/resources/KisTagModel.cpp
+++ b/libs/resources/KisTagModel.cpp
@@ -729,8 +729,8 @@ bool KisTagModel::lessThan(const QModelIndex &source_left, const QModelIndex &so
} else if (rightIsFakeRow) {
return false;
} else {
- QString nameLeft = sourceModel()->data(source_left, Qt::UserRole + KisAllTagsModel::Name).toString().toLower();
- QString nameRight = sourceModel()->data(source_right, Qt::UserRole + KisAllTagsModel::Name).toString().toLower();
- return (nameLeft < nameRight);
+ QString nameLeft = sourceModel()->data(source_left, Qt::UserRole + KisAllTagsModel::Name).toString();
+ QString nameRight = sourceModel()->data(source_right, Qt::UserRole + KisAllTagsModel::Name).toString();
+ return nameLeft.compare(nameRight, Qt::CaseInsensitive) < 0;
}
}
diff --git a/libs/resources/KisTagResourceModel.cpp b/libs/resources/KisTagResourceModel.cpp
index 675a07eeced..05d9dbd6f07 100644
--- a/libs/resources/KisTagResourceModel.cpp
+++ b/libs/resources/KisTagResourceModel.cpp
@@ -873,7 +873,7 @@ bool KisTagResourceModel::lessThan(const QModelIndex &source_left, const QModelI
{
QString nameLeft = sourceModel()->data(source_left, Qt::UserRole + KisAllTagResourceModel::ResourceName).toString();
QString nameRight = sourceModel()->data(source_right, Qt::UserRole + KisAllTagResourceModel::ResourceName).toString();
- return nameLeft.toLower() < nameRight.toLower();
+ return nameLeft.compare(nameRight, Qt::CaseInsensitive) < 0;
}
void KisTagResourceModel::storageChanged(const QString &location)
More information about the kimageshop
mailing list