Re: cvs2git profile data
Michael Haggerty <[email protected]> Tue, 14 Dec 2010 06:59:33 +0100
| Newsgroups | gmane.comp.version-control.subversion.cvs2svn.devel |
|---|---|
| Message-ID | <[email protected]> |
On 12/13/2010 05:42 PM, Alex Bennee wrote:
> Our repository currently takes around 6 hours to do a full import (not
> including the actual fast-import into git). It is very much a CPU
> bound problem with the server showing plenty of spare RAM and not
> overly stretched in terms of IO.
>
> I took the opportunity to collect some profiling data with the
> following invocation:
>
> python -m cProfile -o ${IMPORT_GIT_TREE}/profile.data
> ${CVS2GIT_BASE}/cvs2git --options ${SCRIPT_BASE}/repo-cvs2git.options
>
> As the traces aren't too big I've attached them to the attached
> compressed tarball in case anyone finds them useful:
>
> cb5918252c7bb648ff3d46efd5cc76d4 profile1.data
> ebc6d1b39369c6118d984da9da3f37c2 profile2.data
> edbeed7d077fb7f647de23f523764168 profile.tar.bz2
Thanks for the data.
I suppose that there are two classes of CVS repository--those with few
tags (e.g., tags only set manually) and those with a huge number of tags
(e.g., tags set by nightly scripts), and that these two classes will
have very different performance profiles. I suspect that yours is one
of the latter :-)
The expensive thing about tags is tabulating the possible parents for
each tag. This is expensive for many-tag repositories because the
number of possible parent combinations scales something like
number_of_files * number_of_revisions_per_file *
average(number_of_tags_per_revision^2)
It is the average of the square that is fatal.
In case anybody is interested, here are the top 50 functions by "time"
(time executing, not including time spent in subroutines), with a few notes:
> ncalls tottime percall cumtime percall filename:lineno(function)
> 373089404 2123.950 0.000 3845.862 0.000 record_table.py:301(_get_packed_record)
Most of the calls to _get_packed_record originate from
changeset.py:201(create_graph_node) or from
changeset.py:35(iter_cvs_items). It might make sense to fiddle with the
cache sizes for these cases and/or implement smarter cache management.
> 772823585 1866.751 0.000 4029.054 0.000 symbol_statistics.py:127(register_possible_parent)
This routine could probably be sped up by using a defaultdict (available
starting in Python 2.5) and by inlining it (it is only called from four
places). The statistics could be collected by symbol.id rather than by
symbol instance (this would save lookup time and time calling hash()).
> 493196569 1540.437 0.000 1540.437 0.000 {method 'seek' of 'file' objects}
> 987566288 1453.528 0.000 1940.198 0.000 {method 'get' of 'dict' objects}
> 373089404 1418.363 0.000 6775.321 0.000 record_table.py:156(__getitem__)
This can be grouped together with _get_packed_record() above.
> 18494346 1333.759 0.000 5710.188 0.000 symbol_statistics.py:158(register_tag_possible_parents)
This can be grouped with register_possible_parents().
> 7610543 1295.604 0.000 1295.604 0.000 {posix.read}
> 18460594 1285.036 0.000 3576.792 0.000 cvs_file_items.py:937(_adjust_tag_parent)
> 172135 1245.699 0.007 1245.699 0.007 {posix.fork}
The fork calls come from
abstract_rcs_revision_manager.py:52(get_content), which suggests that
you are not using the internal code for extracting content from the CVS
repository. The internal code should be much faster; I suggest you give
it a try.
> 1624503008 1218.073 0.000 1218.073 0.000 cvs_file_items.py:162(__getitem__)
About 80% of these are also related to register_possible_parents()
> 141412502/140436990 1216.242 0.000 3512.304 0.000 {built-in method load}
> 7351497 1052.883 0.000 1052.883 0.000 {select.select}
> 129257276 1042.738 0.000 1723.673 0.000 cvs_item.py:902(__setstate__)
Used by the unpickler to deserialize data from a database.
> 1627930367 960.929 0.000 960.929 0.000 symbol.py:92(__hash__)
This can be grouped with register_possible_parents().
> 41017875 845.774 0.000 994.289 0.000 {method 'dump' of 'cPickle.Pickler' objects}
> 116908826 749.503 0.000 1206.156 0.000 cvs_path.py:108(get_ancestry)
> 3957 736.786 0.186 9944.325 2.513 changeset.py:201(create_graph_node)
> 1235605900 736.408 0.000 736.408 0.000 {method 'append' of 'list' objects}
> 359311380 647.905 0.000 7177.574 0.000 record_table.py:180(get)
> 70271708 645.909 0.000 908.297 0.000 cvs_item.py:920(check_links)
> 793950954 586.862 0.000 586.862 0.000 {isinstance}
> 373089154 581.802 0.000 827.398 0.000 struct.py:77(unpack)
> 141412475/140436963 486.478 0.000 4371.091 0.000 serializer.py:112(loadf)
> 120728289 479.019 0.000 7294.611 0.000 database.py:278(get_many)
> 505402041 460.134 0.000 460.134 0.000 context.py:34(__init__)
> 121070219/120094707 459.199 0.000 4033.169 0.000 database.py:251(_fetch)
> 251775799 452.962 0.000 1014.617 0.000 record_table.py:87(unpack)
> 100541012 445.162 0.000 1917.926 0.000 cvs_path.py:123(get_cvs_path)
> 37107960/16706495 444.285 0.000 806.241 0.000 cvs_file_items.py:275(process_subitems)
> 616457618 438.568 0.000 438.568 0.000 symbol.py:95(__eq__)
> 9045 416.672 0.046 1532.262 0.169 record_table.py:260(flush)
> 67267307 409.684 0.000 506.029 0.000 default.py:42(get)
> 330776658 358.450 0.000 358.450 0.000 {method 'read' of 'file' objects}
> 182614160 334.610 0.000 334.610 0.000 {method 'copy' of 'dict' objects}
> 959617 320.840 0.000 334.785 0.000 {method 'sort' of 'list' objects}
> 248269119/50550962 317.488 0.000 407.532 0.000 dvcs_common.py:284(_get_all_files)
> 40490955 299.989 0.000 489.128 0.000 {built-in method sub}
> 508653202/508653145 291.446 0.000 291.446 0.000 {len}
> 81500565 276.358 0.000 641.565 0.000 sort.py:65(merge)
> 120729184 272.453 0.000 486.971 0.000 common.py:99(path_join)
> 29340120 263.135 0.000 424.050 0.000 cvs_item.py:775(__setstate__)
> 192774367 259.894 0.000 371.854 0.000 cvs_path.py:172(__cmp__)
> 339920625 253.470 0.000 253.470 0.000 symbol_database.py:43(get_symbol)
> 373089154 245.596 0.000 245.596 0.000 {method 'unpack' of 'Struct' objects}
> 121313355 230.736 0.000 496.478 0.000 record_table.py:122(unpack)
> 321183467 229.498 0.000 237.798 0.000 {method 'add' of 'set' objects}
> 120728289 224.708 0.000 2641.808 0.000 record_table.py:169(get_many)
> 201162141 221.501 0.000 221.501 0.000 {method 'write' of 'file' objects}
> 706426 215.915 0.000 402.004 0.001 cvs_item.py:497(check_links)
> 2181 214.017 0.098 603.593 0.277 {sorted}
--
Michael Haggerty
[email protected]
http://softwareswirl.blogspot.com/
------------------------------------------------------
http://cvs2svn.tigris.org/ds/viewMessage.do?dsForumId=1667&dsMessageId=2690585
To unsubscribe from this discussion, e-mail: [[email protected]].