[PATCH 2 of 2] osutil.c: replace alloca() with malloc() and remove <alloca.h>
Giorgos Keramidas
keramida at ceid.upatras.gr
Sun Oct 7 23:03:47 UTC 2007
On 2007-10-07 23:56, Benoit Boissinot <benoit.boissinot at ens-lyon.org> wrote:
>On Mon, Oct 08, 2007 at 12:43:09AM +0300, Giorgos Keramidas wrote:
>>On 2007-10-07 23:26, Benoit Boissinot <bboissin at gmail.com> wrote:
>>>On 10/7/07, Giorgos Keramidas <keramida at ceid.upatras.gr> wrote:
>>>> The <alloca.h> header is not really portable, and it breaks Mercurial on
>>>> FreeBSD. Remove the dependency on <alloca.h> and alloca() by replacing
>>>> the only place where it was used with malloc().
>>>
>>> Have you done a performance test to see wether it has an impact or not ?
>>
>> Not really, how should I go about testing that this is not a performance
>> regression? I ssuspect there's going to be a minor overhead because of
>> an extra function call for the free() I added, but it would be nice to
>> be able to produce useful performance test results.
>
> hg status on a huge repo ?
Interesting results.
After adding <stdlib.h> the mercurial/osutil.c file compiles correctly
either with alloca() or malloc(), so I used this to run "hg --lsprof
stat" and "hg --profile stat" on a snapshot of the FreeBSD src/ tree,
with around 37000 files:
% keramida at kobe:/home/keramida/hg/freebsd/head> hg manif | wc -l
% 37322
% keramida at kobe:/home/keramida/hg/freebsd/head>
The results are attached as four files:
% hg-lsprof-alloca.txt ; output of "hg --lsprof stat" with alloca()
% hg-lsprof-malloc.txt ; output of "hg --lsprof stat" with malloc()
% hg-profile-alloca.txt ; output of "hg --profile stat" with alloca()
% hg-profile-malloc.txt ; output of "hg --profile stat" with malloc()
Running "diff -u /tmp/hg-lsprof*" produces no output. So the change
from malloc() to alloca() and vice versa is not visibly different here.
The results of "hg --profile" are a bit interesting, however. The
version of osutil.c which uses malloc() seems to be a bit faster, which
is odd :-/
For example, this part is rather odd (alloca = '-', malloc = '+'):
% --- hg-profile-alloca.txt 2007-10-08 01:52:39.000000000 +0300
% +++ hg-profile-malloc.txt 2007-10-08 01:54:08.000000000 +0300
% @@ -1,49 +1,49 @@
% ? hg.prof
% - 394369 function calls (394323 primitive calls) in 7.126 CPU seconds
% + 394369 function calls (394323 primitive calls) in 6.742 CPU seconds
%
% Ordered by: internal time, call count
% List reduced from 67 to 40 due to restriction <40>
%
% ncalls tottime percall cumtime percall filename:lineno(function)
% - 1 4.900 4.900 6.087 6.087 dirstate.py:404(findfiles)
% - 83039 0.428 0.000 0.428 0.000 posixpath.py:56(join)
% - 1 0.352 0.352 0.578 0.578 dirstate.py:124(_read)
% - 1 0.250 0.250 7.122 7.122 dirstate.py:493(status)
% - 37322 0.221 0.000 0.221 0.000 struct.py:77(unpack)
% - 37324 0.198 0.000 6.292 0.000 dirstate.py:352(statwalk)
% - 37323 0.171 0.000 0.240 0.000 dirstate.py:376(imatch)
% - 37323 0.159 0.000 0.379 0.000 dirstate.py:333(_supported)
% - 37323 0.152 0.000 0.220 0.000 stat.py:54(S_ISREG)
% - 41518 0.075 0.000 0.075 0.000 util.py:1131(pconvert)
% - 37323 0.069 0.000 0.069 0.000 util.py:252(always)
% + 1 4.617 4.617 5.755 5.755 dirstate.py:404(findfiles)
% + 83039 0.407 0.000 0.407 0.000 posixpath.py:56(join)
% + 1 0.334 0.334 0.541 0.541 dirstate.py:124(_read)
% + 1 0.240 0.240 6.738 6.738 dirstate.py:493(status)
% + 37322 0.200 0.000 0.200 0.000 struct.py:77(unpack)
% + 37324 0.194 0.000 5.954 0.000 dirstate.py:352(statwalk)
% + 37323 0.167 0.000 0.233 0.000 dirstate.py:376(imatch)
% + 37323 0.153 0.000 0.365 0.000 dirstate.py:333(_supported)
% + 37323 0.144 0.000 0.212 0.000 stat.py:54(S_ISREG)
% + 41518 0.073 0.000 0.073 0.000 util.py:1131(pconvert)
This may be an artifact of the malloc() and alloca() implementation of
FreeBSD, so I'll run the same test on Linux and Solaris and report back
tomorrow; I don't have access to a Solaris machine now :(
In the mean time, is there any other command which would be interesting
to run with --profile and --lsprof?
- Giorgos
-------------- next part --------------
? hg.prof
-------------- next part --------------
? hg.prof
-------------- next part --------------
? hg.prof
394369 function calls (394323 primitive calls) in 7.126 CPU seconds
Ordered by: internal time, call count
List reduced from 67 to 40 due to restriction <40>
ncalls tottime percall cumtime percall filename:lineno(function)
1 4.900 4.900 6.087 6.087 dirstate.py:404(findfiles)
83039 0.428 0.000 0.428 0.000 posixpath.py:56(join)
1 0.352 0.352 0.578 0.578 dirstate.py:124(_read)
1 0.250 0.250 7.122 7.122 dirstate.py:493(status)
37322 0.221 0.000 0.221 0.000 struct.py:77(unpack)
37324 0.198 0.000 6.292 0.000 dirstate.py:352(statwalk)
37323 0.171 0.000 0.240 0.000 dirstate.py:376(imatch)
37323 0.159 0.000 0.379 0.000 dirstate.py:333(_supported)
37323 0.152 0.000 0.220 0.000 stat.py:54(S_ISREG)
41518 0.075 0.000 0.075 0.000 util.py:1131(pconvert)
37323 0.069 0.000 0.069 0.000 util.py:252(always)
37324 0.068 0.000 0.068 0.000 stat.py:29(S_IFMT)
4196 0.057 0.000 0.057 0.000 posixpath.py:373(normpath)
4195 0.008 0.000 0.008 0.000 util.py:253(never)
11/10 0.007 0.001 0.013 0.001 demandimport.py:43(_load)
18 0.006 0.000 0.006 0.000 demandimport.py:80(_demandimport)
4 0.003 0.001 0.582 0.146 dirstate.py:27(__getattr__)
55/10 0.001 0.000 0.013 0.001 demandimport.py:71(__getattribute__)
2 0.000 0.000 0.000 0.000 util.py:1347(__call__)
1 0.000 0.000 0.001 0.001 dirstate.py:8(<module>)
1 0.000 0.000 0.000 0.000 ignore.py:24(ignore)
1 0.000 0.000 7.126 7.126 commands.py:2536(status)
13 0.000 0.000 0.000 0.000 demandimport.py:31(__init__)
1 0.000 0.000 0.000 0.000 dirstate.py:18(dirstate)
1 0.000 0.000 0.000 0.000 cmdutil.py:211(matchpats)
1 0.000 0.000 7.122 7.122 localrepo.py:872(status)
2 0.000 0.000 0.000 0.000 util.py:708(__call__)
1 0.000 0.000 0.000 0.000 ui.py:371(write)
1 0.000 0.000 0.000 0.000 ui.py:291(_configitems)
1 0.000 0.000 0.003 0.003 cmdutil.py:97(revpair)
1 0.000 0.000 7.126 7.126 dispatch.py:340(<lambda>)
1 0.000 0.000 0.000 0.000 ConfigParser.py:527(items)
1 0.000 0.000 0.000 0.000 struct.py:43(calcsize)
1 0.000 0.000 0.000 0.000 dirstate.py:71(getcwd)
1 0.000 0.000 0.000 0.000 util.py:409(cmdmatcher)
2 0.000 0.000 0.001 0.000 dirstate.py:110(parents)
1 0.000 0.000 0.002 0.002 localrepo.py:87(__getattr__)
2 0.000 0.000 0.000 0.000 util.py:144(_interpolate)
1 0.000 0.000 0.003 0.003 struct.py:27(<module>)
1 0.000 0.000 0.000 0.000 dirstate.py:84(pathto)
-------------- next part --------------
? hg.prof
394369 function calls (394323 primitive calls) in 6.742 CPU seconds
Ordered by: internal time, call count
List reduced from 67 to 40 due to restriction <40>
ncalls tottime percall cumtime percall filename:lineno(function)
1 4.617 4.617 5.755 5.755 dirstate.py:404(findfiles)
83039 0.407 0.000 0.407 0.000 posixpath.py:56(join)
1 0.334 0.334 0.541 0.541 dirstate.py:124(_read)
1 0.240 0.240 6.738 6.738 dirstate.py:493(status)
37322 0.200 0.000 0.200 0.000 struct.py:77(unpack)
37324 0.194 0.000 5.954 0.000 dirstate.py:352(statwalk)
37323 0.167 0.000 0.233 0.000 dirstate.py:376(imatch)
37323 0.153 0.000 0.365 0.000 dirstate.py:333(_supported)
37323 0.144 0.000 0.212 0.000 stat.py:54(S_ISREG)
41518 0.073 0.000 0.073 0.000 util.py:1131(pconvert)
37324 0.068 0.000 0.068 0.000 stat.py:29(S_IFMT)
37323 0.066 0.000 0.066 0.000 util.py:252(always)
4196 0.053 0.000 0.053 0.000 posixpath.py:373(normpath)
4195 0.008 0.000 0.008 0.000 util.py:253(never)
11/10 0.007 0.001 0.014 0.001 demandimport.py:43(_load)
18 0.006 0.000 0.006 0.000 demandimport.py:80(_demandimport)
4 0.003 0.001 0.546 0.136 dirstate.py:27(__getattr__)
55/10 0.001 0.000 0.014 0.001 demandimport.py:71(__getattribute__)
2 0.000 0.000 0.001 0.000 util.py:1347(__call__)
1 0.000 0.000 0.001 0.001 dirstate.py:8(<module>)
13 0.000 0.000 0.000 0.000 demandimport.py:31(__init__)
1 0.000 0.000 6.742 6.742 commands.py:2536(status)
1 0.000 0.000 0.000 0.000 ignore.py:24(ignore)
1 0.000 0.000 0.000 0.000 cmdutil.py:211(matchpats)
1 0.000 0.000 0.000 0.000 dirstate.py:18(dirstate)
2 0.000 0.000 0.000 0.000 util.py:708(__call__)
1 0.000 0.000 6.738 6.738 localrepo.py:872(status)
1 0.000 0.000 0.000 0.000 ui.py:371(write)
1 0.000 0.000 0.004 0.004 cmdutil.py:97(revpair)
1 0.000 0.000 0.000 0.000 ui.py:291(_configitems)
1 0.000 0.000 0.000 0.000 dirstate.py:71(getcwd)
1 0.000 0.000 0.000 0.000 struct.py:43(calcsize)
1 0.000 0.000 6.742 6.742 dispatch.py:340(<lambda>)
1 0.000 0.000 0.000 0.000 ConfigParser.py:527(items)
1 0.000 0.000 0.000 0.000 util.py:409(cmdmatcher)
1 0.000 0.000 0.003 0.003 localrepo.py:87(__getattr__)
1 0.000 0.000 0.004 0.004 struct.py:27(<module>)
2 0.000 0.000 0.000 0.000 util.py:144(_interpolate)
1 0.000 0.000 0.000 0.000 ui.py:305(configitems)
2 0.000 0.000 0.001 0.000 dirstate.py:110(parents)
More information about the Mercurial-devel
mailing list