将std :: string转换为大写:主要性能差异?

Mr.*_*ama 8 c++

所以我正在玩一些代码,并希望看到将std :: string转换为大写的哪种方法效率最高.我认为两者在性能方面会有些相似,但我非常错误.现在我想找出原因.

转换字符串的第一种方法如下:对于字符串中的每个字符(保存长度,从0到长度迭代),如果它在'a'和'z'之间,则将其移位以使其在'A'之间和'Z'代替.

第二种方法的工作原理如下:对于字符串中的每个字符(从0开始,一直持续到我们点击空终止符),在toupper()函数中应用构建.

这是代码:

#include <iostream>
#include <string>

inline std::string ToUpper_Reg(std::string str)
{
    for (int pos = 0, sz = str.length(); pos < sz; ++pos)
    {
        if (str[pos] >= 'a' && str[pos] <= 'z') { str[pos] += ('A' - 'a'); }
    }

    return str;
}

inline std::string ToUpper_Alt(std::string str)
{
    for (int pos = 0; str[pos] != '\0'; ++pos) { str[pos] = toupper(str[pos]); }

    return str;
}


int main()
{
    std::string test = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*()_+=-`'{}[]\\|\";:<>,./?";

    for (size_t i = 0; i < 100000000; ++i) { ToUpper_Reg(test); /* ToUpper_Alt(test); */ }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

第一种方法每1亿次迭代ToUpper_Reg花费大约169秒.
第二种方法每1亿次迭代Toupper_Alt花费大约379秒.

是什么赋予了?


编辑:我更改了第二个方法,以便它迭代字符串第一个方法如何(将长度放在一边,循环时小于长度)并且它稍微快一点,但仍然是慢两倍.


编辑2:感谢大家的提交!我将使用它的数据保证是ascii,所以我认为我将暂时坚持使用第一种方法.我会记住,这toupper是特定于何时/如果我需要的语言环境.

Nic*_*las 13

std::toupper使用当前语言环境进行大小写转换,包括函数调用和其他抽象.很自然地,它会变慢.但它也适用于非ASCII文本.


bam*_*s53 5

toupper()不只是移动范围[az]中的字符.一方面,它依赖于语言环境,可以处理的不仅仅是ASCII.