Reputation: 11409
I have created my custom function to turn a wstring into lower case. However, it is pretty slow in DebugMode. Yes, I know ReleaseMode is what counts, but anyway it is pretty unnerving.
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;
}
Does anybody see anything obvious that I could improve to speed up the code, even in DebugMode?
Thank you!
Upvotes: 1
Views: 199
Reputation: 866
First of all I would avoid to allocate memory for variables each run, since allocating is a heavy operation.
Then do not call u.size() in the for-loop declaration. It will be called every loop otherwise. Every function call less that you call in a loop is a good win for performance.
Next everything Nemanja Boric said in the other answer.
And since the variable u is passed as copy, you can use it as return value and operate directly on it.
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;
}
Conclusion: Basically avoid to allocate memory or calling functions in loops. Do just as much as you really have to.
Upvotes: 3
Reputation: 15870
There is actually no need for the wstringToLower
function at all. You can use <algorithm>
to do most of the work:
std::wstring str = "Some String";
std::transform(str.begin(), str.end(), str.begin(), ::towlower);
If you are trying to localize it, you may want to modify it slightly:
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);
});
Upvotes: 0
Reputation: 22187
There's no need to make temporary strings.
So, for start, instead of:
wstring sNewChar=wstring(1,iNewChar);
s.append(sNewChar);
This should do the trick:
s.push_back(iNewChar);
Then, instead of:
wstring sChar;
sChar=u.substr(i,1);
int iChar=static_cast<int>(sChar[0]);
This should work:
int iChar=static_cast<int>(u[i]);
And, of course, as noted by Marcel, you can do everything on the passed copy, avoiding the extra string allocation.
Also, as noted in the comments: How to convert std::string to lower case? . Also, read all answers (and comments) here: 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
Upvotes: 7