【问题标题】:C++ Code optimizationC++ 代码优化
【发布时间】:2013-11-25 18:43:59
【问题描述】:

我创建了自定义函数来将 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 中也是如此?

谢谢!

【问题讨论】:

标签: c++ performance optimization


【解决方案1】:

无需制作临时字符串。

所以,开始,而不是:

    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 所说,您可以在传递的副本上做任何事情,避免额外的字符串分配。

此外,如 cmets 中所述:How to convert std::string to lower case?。另外,请在此处阅读所有答案(和 cmets):how to Make lower case letters for unicode characters:

#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

【讨论】:

  • 实际上根本不需要s。他可以对u 执行所有操作并将其返回并避免多余的副本。
  • @ZacHowland 你是完全正确的,我不知道我是怎么错过的——只是在 Marcel 的回答中看到了。
  • @NemanjaBoric 谢谢。 ::setlocale(LC_ALL,"");你太棒了!
【解决方案2】:

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

那么不要在for循环声明中调用u.size()。否则每个循环都会调用它。每个函数调用的次数比循环调用的次数少,对性能来说是一个很好的胜利。

接下来 Nemanja Boric 在另一个答案中所说的一切。

并且由于变量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;
}

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

【讨论】:

    【解决方案3】:

    实际上根本不需要wstringToLower 函数。您可以使用&lt;algorithm&gt; 完成大部分工作:

    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);
    });
    

    【讨论】:

      猜你喜欢
      • 2012-11-13
      • 1970-01-01
      • 2013-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-01
      相关资源
      最近更新 更多