C++代码优化

C++ Code optimization

本文关键字:代码优化 C++      更新时间:2023-10-16

我已经创建了自定义函数来将wstring转换为小写。然而,在DebugMode中它相当慢。是的,我知道ReleaseMode才是最重要的,但无论如何,它都很令人不安。

wstring wstringToLower(wstring u)
{
    wstring s;
    for (int i=0;i<u.size();i++)
    {
        wstring sChar;
        sChar=u.substr(i,1);
        int iChar=static_cast<int>(sChar[0]);
        int iNewChar=charCodeToLower(iChar);
        wstring sNewChar=wstring(1,iNewChar);
        s.append(sNewChar);
    }
    return s;
}

有没有人看到我可以改进以加快代码的速度,即使是在DebugMode中?

谢谢!

不需要制作临时字符串。

因此,作为开始,而不是:

    wstring sNewChar=wstring(1,iNewChar);
    s.append(sNewChar);

这应该会奏效:

    s.push_back(iNewChar);

然后,而不是:

    wstring sChar;
    sChar=u.substr(i,1);
    int iChar=static_cast<int>(sChar[0]);

这应该有效:

    int iChar=static_cast<int>(u[i]);

当然,正如Marcel所指出的,您可以对传递的副本执行所有操作,从而避免额外的字符串分配。

此外,正如评论中所指出的:如何将std::string转换为小写。此外,请阅读此处的所有答案(和注释):如何为unicode字符制作小写字母:

#include <algorithm>
#include <string>
#include <iostream>
using namespace std;

int main()
{
        ::setlocale(LC_ALL,"");
        std::wstring data = L"НЕМАЊА БОРИЋ"; // Wide chars
        std::transform(data.begin(), data.end(), data.begin(), ::towlower);
        // prints немања борић
        std::wcout << data << std::endl;
        return 0;
}

http://en.cppreference.com/w/cpp/string/wide/towlower

首先,我会避免每次运行都为变量分配内存,因为分配是一项繁重的操作。

然后不要在for循环声明中调用u.size()。否则将在每个循环中调用它。在循环中调用的每一个函数都是性能上的一大优势。

接下来,尼曼加·博里奇在另一个回答中所说的一切。

由于变量u是作为副本传递的,您可以将其用作返回值并直接对其进行操作

wstring wstringToLower(wstring u)
{
    int size = u.size();
    for (int i = 0; i < size; ++i)
    {
        u[i] = charCodeToLower(static_cast<int>(u[i]));
    }
    return u;
}

结论:基本上避免在循环中分配内存或调用函数。尽你所能。

实际上根本不需要wstringToLower函数。您可以使用<algorithm>来完成大部分工作:

std::wstring str = "Some String";
std::transform(str.begin(), str.end(), str.begin(), ::towlower);

如果你想本地化它,你可能想稍微修改一下:

std::wstring str = "Some String";
std::locale loc; // set your locale
std::transform(str.begin(), str.end(), str.begin(), [](wchar_t c)
{
    return use_facet<ctype<wchar_t>>(loc).tolower(c);
});