Discussion:
[perl #114834] comctl32.dll / 4ebea3c6 causes a 44% slowdown on one liners on Win32
bulk 88 (via RT)
2012-09-11 07:07:01 UTC
Permalink
# New Ticket Created by bulk 88
# Please include the string: [perl #114834]
# in the subject line of all future correspondence about this issue.
# <URL: https://rt.perl.org:443/rt3/Ticket/Display.html?id=114834 >


This is a bug report for perl from ***@hotmail.com,
generated with the help of perlbug 1.39 running under perl 5.17.4.


-----------------------------------------------------------------
[Please describe your issue here]

Summary: In Perl 5.11 a commit was done for Perl to load a Win32 GUI
Library it will never use. I measured that a -e "0;" invocation of
Perl 5.17 takes %44 more time wall time than the same Perl 5.17 with
the GUI library removed.

In http://perl5.git.perl.org/perl.git/commit/4ebea3c679ca93eb90d62be76bf8eb3cd7d14160
a dependency on comctl32.dll was added to Perl. Perl 5.10 didn't have
this dependency, 5.12 did. Comctl32 provides various common GUI dialog
boxes for Windows. Comctl32 v6 on WinXP also causes shlwapi.dll to be
loaded into the process. I dont feel that loading this DLL
automatically on every Perl process startup is justified. Perl never
draws any GUI components on Windows. I guess this was an quick fix to
enable XP theming in various GUI drawing CPAN Win32::* modules without
fixing the relevant modules individually. InitCommonControls is also
called from Strawberry Perl 5.12, but no manifest is created or
attached in the GCC Win32 Perl build system, so GCC Win32 Perls always
wind up with the legacy theme.

The manifest part of the commit is fine (requesting but not loading
comctl32 v6 in perl51*.dll's manifest and requestedExecutionLevel for
Win NT 6 UAC).

To see if comctl32 has a negative impact on startup time, I used the
following script.
__________________________________________________
#!/usr/bin/perl -w
use Benchmark;
sub run {
system($^X, '-e "0;"');
}
timethis(3000, \&run);
__________________________________________________
The Perl used for testing is a 5.17, -O1 (ignore the config.pm data)
with DEBUGGING. I disabled comctl32 from being linked by commenting
out
__________________________________________________
InitCommonControls();
__________________________________________________
in Perl_win32_init in win32.c (
http://perl5.git.perl.org/perl.git/blob/f43bd6ba6956056680521efe81a53b27ad254e08:/win32/win32.c#l4266
) and doing a rapid rebuild using a custom batch file (2-3 minutes) of
perl517.dll. comctl32 removal was verified by looking at the import
table of perl517.dll. My results were.

without comctl32:
__________________________________________________
C:\Documents and Settings\Owner\Desktop>perl oneline.pl
timethis 3000: 29 wallclock secs ( 0.56 usr + 1.17 sys = 1.73 CPU) @ 1731.10/s
(n=3000)

C:\Documents and Settings\Owner\Desktop>
__________________________________________________

with comctl32:
__________________________________________________

C:\Documents and Settings\Owner\Desktop>perl oneline.pl
timethis 3000: 42 wallclock secs ( 0.63 usr + 1.39 sys = 2.02 CPU) @ 1488.10/
(n=3000)

C:\Documents and Settings\Owner\Desktop>
__________________________________________________
In my opinion the wallclock times are the most impressive since alot
of Windows GUI system implemented as a kernel driver and or
synchronous IPC to daemons. I also created 2 Dependency Walker logs
for Perl 5.17 to show the difference (see attachments).

In the near future, as a separate ticket, I plan to investigate
whether turning advapi32.dll (and therefore not always loading
rpcrt4.dll and secur32.dll) into a delay loaded dll by perl517.dll
will improve startup time of one liners that never touch @INC without
negatively affecting startup time of module loading scripts.

So my proposal is to remove InitCommonControls() from Perl_win32_init
in win32.c, which will remove Perl's dependency on comctl32.dll and
shlwapi.dll and therefore speeding up startup time. So what are
everyones comments on the issue? If I write a patch, will anyone
commit it?


[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
category=core
severity=low
---
Site configuration information for perl 5.17.4:

Configured by Owner at Fri Sep 7 20:13:21 2012.

Summary of my perl5 (revision 5 version 17 subversion 4 patch blead
2012-08-19.11:53:47 0374b0a2a50c6e91951723a4d9ee1d7f534b03eb
v5.17.2-394-g0374b0a) configuration:
Snapshot of: 0374b0a2a50c6e91951723a4d9ee1d7f534b03eb
Platform:
osname=MSWin32, osvers=5.1, archname=MSWin32-x86-multi-thread
uname=''
config_args='undef'
hint=recommended, useposix=true, d_sigaction=undef
useithreads=define, usemultiplicity=define
useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
use64bitint=undef, use64bitall=undef, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cl', ccflags ='-nologo -GF -W3 -Od -MD -Zi -DDEBUGGING -DWIN32
-D_CONSOLE -DNO_STRICT -DPERL_POISON -DPERL_TEXTMODE_SCRIPTS
-DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO
-D_USE_32BIT_TIME_T',
optimize='-Od -MD -Zi -DDEBUGGING',
cppflags='-DWIN32'
ccversion='13.10.6030', gccversion='', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=8
ivtype='long', ivsize=4, nvtype='double', nvsize=8,
Off_t='__int64', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='link', ldflags ='-nologo -nodefaultlib -debug
-libpath:"c:\perl517\lib\CORE" -machine:x86'
libpth="C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\lib"
libs=oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib
netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib version.lib
odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib
perllibs=oldnames.lib kernel32.lib user32.lib gdi32.lib
winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib
oleaut32.lib netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib
version.lib odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib
libc=msvcrt.lib, so=dll, useshrplib=true, libperl=perl517.lib
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug
-libpath:"c:\perl517\lib\CORE" -machine:x86'

Locally applied patches:


---
@INC for perl 5.17.4:
C:/perl517/site/lib
C:/perl517/lib
.

---
Environment for perl 5.17.4:
HOME (unset)
LANG (unset)
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=C:\perl517\bin;C:\Program Files\Microsoft Visual Studio .NET
2003\Common7\IDE;C:\Program Files\Microsoft Visual Studio .NET
2003\VC7\BIN;C:\Program Files\Microsoft Visual Studio .NET
2003\Common7\Tools;C:\Program Files\Microsoft Visual Studio .NET
2003\Common7\Tools\bin\prerelease;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\system32\wbem;
PERL_BADLANG (unset)
SHELL (unset)
Jan Dubois
2012-09-11 08:45:41 UTC
Permalink
Post by bulk 88 (via RT)
In http://perl5.git.perl.org/perl.git/commit/4ebea3c679ca93eb90d62be76bf8eb3cd7d14160
a dependency on comctl32.dll was added to Perl. Perl 5.10 didn't have
this dependency, 5.12 did. Comctl32 provides various common GUI dialog
boxes for Windows. Comctl32 v6 on WinXP also causes shlwapi.dll to be
loaded into the process. I dont feel that loading this DLL
automatically on every Perl process startup is justified. Perl never
draws any GUI components on Windows. I guess this was an quick fix to
enable XP theming in various GUI drawing CPAN Win32::* modules without
fixing the relevant modules individually. InitCommonControls is also
called from Strawberry Perl 5.12, but no manifest is created or
attached in the GCC Win32 Perl build system, so GCC Win32 Perls always
wind up with the legacy theme.
The manifest part of the commit is fine (requesting but not loading
comctl32 v6 in perl51*.dll's manifest and requestedExecutionLevel for
Win NT 6 UAC).
No, the call to InitCommonControls() exists solely because of the
comctl32 request in the manifest. Check the comment directly on top
of the call; it explains why it was added:

http://perl5.git.perl.org/perl.git/blob/f43bd6ba6956056680521efe81a53b27ad254e08:/win32/win32.c#l4258

Adding the manifest but not loading comctl32.dll at runtime will
break Win32::MsgBox() on Windows XP after a certain hotfix level.
I can't remember if the message box would just not show, or if
the program would hang or crash. I had tracked it down to a
particular Window update hotfix, but can't find the notes anymore.
It should be trivial to reproduce though, if you are curious.

There have been multiple bug reports about this, which is why I
added the InitCommonControls() call in the first place. So I would
suggest that the manifest part should be removed as well *if* the
InitCommonControls() call is removed, turning Perl GUI programs
back to legacy theming by default.
Post by bulk 88 (via RT)
__________________________________________________
__________________________________________________
__________________________________________________
So my proposal is to remove InitCommonControls() from Perl_win32_init
in win32.c, which will remove Perl's dependency on comctl32.dll and
shlwapi.dll and therefore speeding up startup time. So what are
everyones comments on the issue? If I write a patch, will anyone
commit it?
Given that the Perl startup slowdown according to your benchmark above
is less than 0.005s wallclock time (13s over 3000 oneliner invocations),
I find this negligible and would rather have proper GUI theming turned
on by default. So I think any patch should be optional (controlled by
win32/Makefile), and disabled by default.

Cheers,
-Jan
Steve Hay via RT
2012-09-20 07:36:39 UTC
Permalink
Post by Jan Dubois
Adding the manifest but not loading comctl32.dll at runtime will
break Win32::MsgBox() on Windows XP after a certain hotfix level.
I can't remember if the message box would just not show, or if
the program would hang or crash. I had tracked it down to a
particular Window update hotfix, but can't find the notes anymore.
It should be trivial to reproduce though, if you are curious.
There have been multiple bug reports about this, which is why I
added the InitCommonControls() call in the first place. So I would
suggest that the manifest part should be removed as well *if* the
InitCommonControls() call is removed, turning Perl GUI programs
back to legacy theming by default.
Post by bulk 88 (via RT)
__________________________________________________
timethis 3000: 29 wallclock secs ( 0.56 usr + 1.17 sys = 1.73 CPU)
@ 1731.10/s
Post by bulk 88 (via RT)
__________________________________________________
timethis 3000: 42 wallclock secs ( 0.63 usr + 1.39 sys = 2.02 CPU)
@ 1488.10/
Post by bulk 88 (via RT)
__________________________________________________
So my proposal is to remove InitCommonControls() from
Perl_win32_init
Post by bulk 88 (via RT)
in win32.c, which will remove Perl's dependency on comctl32.dll and
shlwapi.dll and therefore speeding up startup time. So what are
everyones comments on the issue? If I write a patch, will anyone
commit it?
Given that the Perl startup slowdown according to your benchmark above
is less than 0.005s wallclock time (13s over 3000 oneliner
invocations),
I find this negligible and would rather have proper GUI theming turned
on by default. So I think any patch should be optional (controlled by
win32/Makefile), and disabled by default.
Given how negligible the speed-up would be, I don't really see any
benefit in even having a Makefile option for this, and am therefore
closing this ticket.

(However, I won't object if someone else wanted to write up a patch to
add such an option, so feel free to re-open the ticket with a suitable
patch if you feel it is worth it.)

---
via perlbug: queue: perl5 status: open
https://rt.perl.org:443/rt3/Ticket/Display.html?id=114834
Olivier Mengué via RT
2015-03-09 23:15:40 UTC
Permalink
An intermediate solution would be to put the manifest and load Comctl32.dll only from wperl.exe but not from perl.exe and from the perl DLL. That way, the GUI programs would get the proper theming, but command-line programs would not get the speed penalty.


---
via perlbug: queue: perl5 status: rejected
https://rt.perl.org/Ticket/Display.html?id=114834
Olivier Mengué via RT
2015-08-03 08:35:20 UTC
Permalink
bluk88, Jan,

Could you comment on this proposal about RT#114834 ?

Olivier.
Post by Olivier Mengué via RT
An intermediate solution would be to put the manifest and load
Comctl32.dll only from wperl.exe but not from perl.exe and from the
perl DLL. That way, the GUI programs would get the proper theming, but
command-line programs would not get the speed penalty.
---
via perlbug: queue: perl5 status: rejected
https://rt.perl.org/Ticket/Display.html?id=114834
Jan Dubois
2015-08-04 18:20:52 UTC
Permalink
I disagree that perl.exe shouldn't call InitCommonControls() by
default, because this breaks Win32::MsgBox (or any other GUI code that
tries to instantiate one of several standard Window classes). The
performance gains are negligible, so not worth confusing new users
about why their GUI elements won't show up.

I agree with Steve
(https://rt.perl.org/Ticket/Display.html?id=114834#txn-1155920):

| (However, I won't object if someone else wanted to write
| up a patch to add such an option, so feel free to re-open
| the ticket with a suitable patch if you feel it is worth it.)

This is about adding an option to the Makefile.

Cheers,
-Jan


On Mon, Aug 3, 2015 at 1:35 AM, Olivier Mengué via RT
Post by Olivier Mengué via RT
bluk88, Jan,
Could you comment on this proposal about RT#114834 ?
Olivier.
Post by Olivier Mengué via RT
An intermediate solution would be to put the manifest and load
Comctl32.dll only from wperl.exe but not from perl.exe and from the
perl DLL. That way, the GUI programs would get the proper theming, but
command-line programs would not get the speed penalty.
---
via perlbug: queue: perl5 status: rejected
https://rt.perl.org/Ticket/Display.html?id=114834
bulk88 via RT
2015-08-12 19:36:41 UTC
Permalink
Post by Olivier Mengué via RT
bluk88, Jan,
Could you comment on this proposal about RT#114834 ?
Ill write a more detailed response later in a few days. Rebenched blead perl with and without comctrl32.

-----------------------------------------------------
use Benchmark qw(:all :hireswallclock) ;

timethese(100, {
'comctrl' => sub { system('C:\p523\comctrl\bin\perl.exe -e"0"') for 0..10},
'nocomctrl' => sub { system('C:\p523\nocomctrl\bin\perl.exe -e"0"') for 0..10},
})
--------------------------------------------------------
C:\p523>perl r.pl
Benchmark: timing 100 iterations of comctrl, nocomctrl...
comctrl: 38.6995 wallclock secs ( 0.19 usr + 1.39 sys = 1.58 CPU) @ 63.37/s
(n=100)
nocomctrl: 20.3301 wallclock secs ( 0.41 usr + 1.12 sys = 1.53 CPU) @ 65.27/s
(n=100)

C:\p523>
---------------------------------------------------------
--
bulk88 ~ bulk88 at hotmail.com

---
via perlbug: queue: perl5 status: rejected
https://rt.perl.org/Ticket/Display.html?id=114834
Loading...