2013-11-25 118 views
0

我已经创建了我的自定义函数来将wstring转换为小写字母。但是,在DebugMode中它非常慢。是的,我知道ReleaseMode是最重要的,但无论如何,这是非常令人不安的。C++代码优化

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中我可以改进以加快代码速度?

谢谢!

+2

http://stackoverflow.com/questions/ 313970/stl-string-to-lower-case - 恐怕你的函数太复杂了50倍。 – Mat

+2

如何为每个角色使用“tolower”? – 0x499602D2

+0

这属于** http://codereview.stackexchange.com/** – lifetimes

回答

7

没有必要制作临时字符串。

所以,开始的不是,:

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所指出的那样,您可以对传递的副本执行所有操作,避免额外的字符串分配。

另外,正如在评论中指出的那样:How to convert std::string to lower case?。此外,阅读所有的答案(和评论)在这里: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

+0

实际上根本不需要's'。他可以在'u'上做所有的操作并返回并避免额外的拷贝。 –

+0

@ZacHowland你是完全正确的,我不知道我是怎么错过的 - 只是在马塞尔的回答中看到了它。 –

+1

@NemanjaBoric谢谢。 ::的setlocale(LC_ALL, “”);你很棒! – tmighty

3

首先,由于分配是一项繁重的操作。

然后不要在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; 
} 

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

0

实际上根本不需要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); 
});