Qt字符串QString比对效率相关

Qt中的QString可以直接使用==进行比较,但是因为之前有发现只读情况下QList::at比使用[]更快的先例,所以在想是不是存在能更快比对两个QString是否相等的方法。

稍微找过之后发现了QString::compare函数。这个函数对输入的两个字符串进行比对,并返回一个int值,表示第一个字符串相较第二个字符串的偏差。Qt5.9.6文档中的描述如下:

[static] int QString::compare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs = Qt::CaseSensitive)

Compares s1 with s2 and returns an integer less than, equal to, or greater than zero if s1 is less than, equal to, or greater than s2.

If cs is Qt::CaseSensitive, the comparison is case sensitive; otherwise the comparison is case insensitive.

Case sensitive comparison is based exclusively on the numeric Unicode values of the characters and is very fast, but is not what a human would expect. Consider sorting user-visible strings with localeAwareCompare().

int x = QString::compare("aUtO", "AuTo", Qt::CaseInsensitive);  // x == 0
int y = QString::compare("auto", "Car", Qt::CaseSensitive);     // y > 0
int z = QString::compare("auto", "Car", Qt::CaseInsensitive);   // z < 0

This function was introduced in Qt 4.2.

虽然我觉得要返回一个带有多余信息(两个字符串谁大谁小)的int值一多半可以断定这个函数没有直接使用双等于号快,不过总之觉得有一试的潜力,所以试了一下。

两种字符串比对方法效率测试程序
#include <QtCore/QCoreApplication>
#include <qtextstream.h>

#include <qdebug.h>
#define myDebug QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC).debug().noquote()<<QString("[%1]").arg(__FUNCTION__)

#include <qelapsedtimer.h>
#include <quuid.h>
#include <qdatetime.h>

/*
 *这个随机字符串函数来自https://blog.csdn.net/hellokandy/article/details/120152085
 */
QString makeRandomString(int length)
{
	QString result;
    
	const char array_str[] = "abcdefghijklmnopqrstuvwxyz";
	int array_size = sizeof(array_str);

	int idx = 0;
	for (int i = 0; i < length; ++i)
	{
		idx = qrand() % (array_size - 1);
		QChar ch = array_str[idx];
		result.push_back(ch);
	}

	return result;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

	qsrand(QDateTime::currentMSecsSinceEpoch());//随机数种子

    QElapsedTimer timer;

    const size_t test_num(10000000);
	const size_t str_max_length(10);
	const size_t str_min_length(5);
	const size_t str_length_range(str_max_length- str_min_length);

    QStringList compare_str_list_1;
    QStringList compare_str_list_2;

    compare_str_list_1.clear();
    compare_str_list_2.clear();

	myDebug << QString::fromLocal8Bit("开始准备测试材料");
	for (int i = 0; test_num > i; i++) {
		compare_str_list_1.push_back(makeRandomString(qrand() % str_length_range + str_min_length));
		compare_str_list_2.push_back(makeRandomString(qrand() % str_length_range + str_min_length));
	}
	myDebug << QString::fromLocal8Bit("测试材料准备完成");

	bool compare_result;

	myDebug << QString::fromLocal8Bit("开始测试==方式");
	timer.start();
	for (int i = 0; test_num > i; i++) {
		compare_result = (compare_str_list_1.at(i)== compare_str_list_2.at(i));
	}
	myDebug << QString::fromLocal8Bit("==方式测试结束: %1 ms").arg(timer.elapsed());

	myDebug << QString::fromLocal8Bit("开始测试QString::compare方式");
	timer.start();
	for (int i = 0; test_num > i; i++) {
		compare_result = (0==QString::compare(compare_str_list_1.at(i), compare_str_list_2.at(i)));
	}
	myDebug << QString::fromLocal8Bit("QString::compare方式测试结束: %1 ms").arg(timer.elapsed());

    return a.exec();
}

 

测试结果,两种方法的效率差距竟接近3倍,直接使用双等于号比对字符串效率明显优于QString::compare

结论:如无字符串排序需要,比对字符串直接使用==就好了。

另:关于涉及中文字符串的排序方式,目前知道可以使用qSort函数加上QCollator完成,不过这方面确实不知道哪个更好一些,等之后再深入了解吧。

posted @ 2022-08-09 11:47  LaEstonteco  阅读(2973)  评论(0)    收藏  举报