Rev 2439: More inner loop tuning of walkdirs, can save as much as 5% in http://bazaar.launchpad.net/%7Ebzr/bzr/dirstate
John Arbash Meinel
john at arbash-meinel.com
Wed Feb 28 22:12:05 GMT 2007
At http://bazaar.launchpad.net/%7Ebzr/bzr/dirstate
------------------------------------------------------------
revno: 2439
revision-id: john at arbash-meinel.com-20070228221101-c3szee94o5h3uvt7
parent: john at arbash-meinel.com-20070228215011-hfmfc13mswbubn18
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: dirstate
timestamp: Wed 2007-02-28 16:11:01 -0600
message:
More inner loop tuning of walkdirs, can save as much as 5%
(drops time on LP tree from 100-105ms, to 95-100ms)
Also, unify all walkdirs variants to have minimal variation.
modified:
bzrlib/osutils.py osutils.py-20050309040759-eeaff12fbf77ac86
-------------- next part --------------
=== modified file 'bzrlib/osutils.py'
--- a/bzrlib/osutils.py 2007-02-28 21:50:11 +0000
+++ b/bzrlib/osutils.py 2007-02-28 22:11:01 +0000
@@ -1079,29 +1079,29 @@
# depending on top and prefix - i.e. ./foo and foo as a pair leads to
# potentially confusing output. We should make this more robust - but
# not at a speed cost. RBC 20060731
- lstat = os.lstat
- pending = []
+ _lstat = os.lstat
_directory = _directory_kind
_listdir = os.listdir
+ _kind_from_mode = _formats.get
pending = [(safe_unicode(prefix), "", _directory, None, safe_unicode(top))]
while pending:
- dirblock = []
- currentdir = pending.pop()
# 0 - relpath, 1- basename, 2- kind, 3- stat, 4-toppath
- relroot = currentdir[0]
- top = currentdir[4]
+ relroot, _, _, _, top = pending.pop()
if relroot:
relprefix = relroot + u'/'
else:
- relprefix = ""
+ relprefix = ''
top_slash = top + u'/'
+
+ dirblock = []
+ append = dirblock.append
for name in sorted(_listdir(top)):
abspath = top_slash + name
- statvalue = lstat(abspath)
- dirblock.append((relprefix + name, name,
- file_kind_from_stat_mode(statvalue.st_mode),
- statvalue, abspath))
+ statvalue = _lstat(abspath)
+ kind = _kind_from_mode(statvalue.st_mode & 0170000, 'unknown')
+ append((relprefix + name, name, kind, statvalue, abspath))
yield (relroot, top), dirblock
+
# push the user specified dirs from dirblock
pending.extend(d for d in reversed(dirblock) if d[2] == _directory)
@@ -1135,38 +1135,32 @@
encoding. So we don't need to transcode filenames.
"""
_lstat = os.lstat
- pending = []
_directory = _directory_kind
_listdir = os.listdir
- _kind_from_mode = file_kind_from_stat_mode
- # TODO: make these assert instead
- if isinstance(top, unicode):
- top = top.encode('utf8')
- if isinstance(prefix, unicode):
- prefix = prefix.encode('utf8')
+ _kind_from_mode = _formats.get
- pending = [(prefix, top)]
+ # 0 - relpath, 1- basename, 2- kind, 3- stat, 4-toppath
+ # But we don't actually uses 1-3 in pending, so set them to None
+ pending = [(safe_utf8(prefix), None, None, None, safe_utf8(top))]
while pending:
- relroot, top = pending.pop()
- if relroot == '':
- rel_prefix = ''
+ relroot, _, _, _, top = pending.pop()
+ if relroot:
+ relprefix = relroot + '/'
else:
- rel_prefix = relroot + '/'
+ relprefix = ''
top_slash = top + '/'
- # In plain for loop form
+
dirblock = []
+ append = dirblock.append
for name in sorted(_listdir(top)):
abspath = top_slash + name
statvalue = _lstat(abspath)
- kind = _kind_from_mode(statvalue.st_mode)
- dirblock.append((rel_prefix + name, name,
- kind, statvalue, abspath))
-
+ kind = _kind_from_mode(statvalue.st_mode & 0170000, 'unknown')
+ append((relprefix + name, name, kind, statvalue, abspath))
yield (relroot, top), dirblock
+
# push the user specified dirs from dirblock
- pending.extend((d[0], d[4])
- for d in reversed(dirblock)
- if d[2] == _directory)
+ pending.extend(d for d in reversed(dirblock) if d[2] == _directory)
def _walkdirs_unicode_to_utf8(top, prefix=""):
@@ -1181,33 +1175,31 @@
"""
_utf8_encode = codecs.getencoder('utf8')
_lstat = os.lstat
- pending = []
_directory = _directory_kind
_listdir = os.listdir
- _kind_from_mode = file_kind_from_stat_mode
+ _kind_from_mode = _formats.get
- pending = [(safe_utf8(prefix), safe_unicode(top))]
+ pending = [(safe_utf8(prefix), None, None, None, safe_unicode(top))]
while pending:
- relroot, top = pending.pop()
- if relroot == '':
- rel_prefix = ''
+ relroot, _, _, _, top = pending.pop()
+ if relroot:
+ relprefix = relroot + '/'
else:
- rel_prefix = relroot + '/'
+ relprefix = ''
top_slash = top + u'/'
- # In plain for loop form
+
dirblock = []
+ append = dirblock.append
for name in sorted(_listdir(top)):
name_utf8 = _utf8_encode(name)[0]
abspath = top_slash + name
statvalue = _lstat(abspath)
- kind = _kind_from_mode(statvalue.st_mode)
- dirblock.append((rel_prefix + name_utf8, name_utf8,
- kind, statvalue, abspath))
+ kind = _kind_from_mode(statvalue.st_mode & 0170000, 'unknown')
+ append((relprefix + name_utf8, name_utf8, kind, statvalue, abspath))
yield (relroot, top), dirblock
+
# push the user specified dirs from dirblock
- pending.extend((d[0], d[4])
- for d in reversed(dirblock)
- if d[2] == _directory)
+ pending.extend(d for d in reversed(dirblock) if d[2] == _directory)
def copy_tree(from_path, to_path, handlers={}):
More information about the bazaar-commits
mailing list