|
-
October 2nd, 2015, 04:21 PM
#1
strange performance behavior in character functions: toupper, tolower, isalpha, ...
In our MFC application, one of our dll will call "tolower" frequently. Here is the sample code:
void foo(char c)
{
for(int i=0;i<200000;++i)
{
aaa += tolower(c);
}
}
I found that there is a very stranger behavior:
1) The tolower function only slow the performance signifcantly when foo is called in the thread of the main process.
if we fork a subprocess, then create a thread to call the function foo, it works fine.
2) The release version is even much slower than the debug version.
I have tested toupper, tolower, isalpha, islower. The same phenomenon will be observed.
But if I change to function sin, it works as fast as running with subprocess
I am using VS2012, MFC.
-
October 3rd, 2015, 01:53 AM
#2
Re: strange performance behavior in character functions: toupper, tolower, isalpha,
 Originally Posted by u11072940
I found that there is a very stranger behavior:
It could be due to different overhead depending on how functions are called.
Slowest would be if a function is called over a dynamically linked interface, faster would be if the function is statically linked and the call resolved at compiletime, and fastest would be if the function isn't called at all but inlined.
So for fastest code, try to ensure that frequently called small functions are inlined.
Last edited by tiliavirga; October 3rd, 2015 at 01:55 AM.
-
October 4th, 2015, 08:14 AM
#3
Re: strange performance behavior in character functions: toupper, tolower, isalpha,
Thanks tiliavirga.
What confuse me is that :
if I change
aaa += tolower(c);
to
aaa += toupper(c); //or isalpha(c), isdigit(c)
the performance issue still can be observed.
But if I change it to
aaa += sin(c);
it works fine
-
October 4th, 2015, 09:56 AM
#4
Re: strange performance behavior in character functions: toupper, tolower, isalpha,
it looks like you have a global locale requiring sychronization, possibly explaining the observed slowdown.
Did you try stepping through tolower() code ?
Did you try the std::tolower version passing a specific local locale ( pun intended ) ?
-
October 5th, 2015, 02:15 AM
#5
Re: strange performance behavior in character functions: toupper, tolower, isalpha,
 Originally Posted by u11072940
What confuse me is that :
If my assumption is correct than an explanation for this behaviour could be that since tolower() and sin() are on different include files they may be linked differently to the program.
A long shot maybe but I've seen weirder stuff in my day.
-
October 5th, 2015, 09:00 AM
#6
Re: strange performance behavior in character functions: toupper, tolower, isalpha,
 Originally Posted by superbonzo
it looks like you have a global locale requiring sychronization, possibly explaining the observed slowdown.
Did you try stepping through tolower() code ?
Did you try the std::tolower version passing a specific local locale ( pun intended  ) ?
Thanks superbonzo, you're right
after step into tolower, its implementation is:
<tolower.cpp>
extern "C" int __cdecl tolower (
int c
)
{
if (__locale_changed == 0)
{
return __ascii_towlower(c); //this is assembly code, fast
}
else
{
return _tolower_l(c, NULL); //slow
}
}
if I change tolower to _tolower_l, now running in subprocess will be as slow as running in main process
From the phenomenon:
it seems that if running in the thread of main process, the __locale_changed will be 1.
while running in the thread of subprocess, __locale_changed will be 0.
I am wondering why ?
Last edited by u11072940; October 5th, 2015 at 12:08 PM.
-
October 5th, 2015, 09:01 AM
#7
Re: strange performance behavior in character functions: toupper, tolower, isalpha,
Yes, sin function is in math.h
<math.h>
inline float __CRTDECL sin(_In_ float _X)
{return (sinf(_X)); } //assembly code
while tolower is in <tolower.cpp>
-
October 5th, 2015, 12:43 PM
#8
Re: strange performance behavior in character functions: toupper, tolower, isalpha,
 Originally Posted by u11072940
I am wondering why ?
I guess you set a global locale somewhere (either in your DLL, or in the main process or in some other DLL, assuming the runtime linked dynamically everywhere ) frequently accessed by multiple threads, hence causing a slowdown due to excessive lock contention. The forked process will have its own runtime, hence its own possibly default C locale ( that is optimized as you noted ).
Concerning a solution and assuming you don't actually need a locale, you could use the locale aware tolower version defined in <locale> as previously suggested; eg. std:: tolower( c, std:: locale:: classic() )
-
October 5th, 2015, 03:22 PM
#9
Re: strange performance behavior in character functions: toupper, tolower, isalpha,
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|