From 48eb2842ee1fb89b0cfb606c2f4096078f9b3482 Mon Sep 17 00:00:00 2001 From: Bastien Jacquet Date: Thu, 13 Nov 2014 05:36:48 +0100 Subject: [PATCH] Optimize FlatNodeMap update of _hndl2index for add/delete tests with python2.6 and python3 show that it's much quicker to get the handles after the inser/deleted index and upgrade those (because random-access in a hash-table is super fast) Here is the code use for tests: import string,random,sys import timeit def id_generator(size=6, chars=string.ascii_lowercase): return ''.join(random.choice(chars) for _ in range(size)) num_items=80000 handle_sizes=10 num_operation=2000 setup=""" from __main__ import id_generator,string,num_items,handle_sizes,random _index2hndl=[("",id_generator(handle_sizes)) for e in range (num_items)] _hndl2index=dict([key[1], index] for index, key in enumerate(_index2hndl)) """ add0=''' h=id_generator(handle_sizes) insert_pos= random.randrange(len(_hndl2index)) srtkey_hndl=("",h) _index2hndl.insert(insert_pos, srtkey_hndl) for hndl, index in _hndl2index.iteritems(): if index >= insert_pos: _hndl2index[hndl] += 1 _hndl2index[h]=insert_pos ''' add1=''' h=id_generator(handle_sizes) insert_pos= random.randrange(len(_hndl2index)) srtkey_hndl=("",h) _index2hndl.insert(insert_pos, srtkey_hndl) for hndl, index in _hndl2index.items(): if index >= insert_pos: _hndl2index[hndl] += 1 _hndl2index[h]=insert_pos ''' add2=''' h=id_generator(handle_sizes) insert_pos= random.randrange(len(_hndl2index)) srtkey_hndl=("",h) _index2hndl.insert(insert_pos, srtkey_hndl) for srt_key,hndl in _index2hndl[insert_pos+1:]: _hndl2index[hndl] += 1 _hndl2index[h]=insert_pos ''' del0=''' index= random.randrange(len(_hndl2index)) srt_key,handle=_index2hndl[index] del _index2hndl[index] del _hndl2index[handle] for key, val in _hndl2index.iteritems(): if val > index: _hndl2index[key] -= 1 ''' del1=''' index= random.randrange(len(_hndl2index)) srt_key,handle=_index2hndl[index] del _index2hndl[index] del _hndl2index[handle] for key, val in _hndl2index.items(): if val > index: _hndl2index[key] -= 1 ''' del2=''' index= random.randrange(len(_hndl2index)) srt_key,handle=_index2hndl[index] del _index2hndl[index] del _hndl2index[handle] for srt_key,hndl in _index2hndl[index:]: _hndl2index[hndl] -= 1 ''' if sys.version_info[0] < 3: cmds=[add0,add1,add2,del0,del1,del2] else: cmds=[add1,add2,del1,del2] for c in cmds: print(c) random.seed(1) t=timeit.Timer(c, setup=setup).timeit(num_operation) print(num_operation,"ops in ", t, "seconds. avg:",t/num_operation,"seconds") --- gramps/gui/views/treemodels/flatbasemodel.py | 22 +++++--------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/gramps/gui/views/treemodels/flatbasemodel.py b/gramps/gui/views/treemodels/flatbasemodel.py index ff5873876..72c77470f 100644 --- a/gramps/gui/views/treemodels/flatbasemodel.py +++ b/gramps/gui/views/treemodels/flatbasemodel.py @@ -200,7 +200,7 @@ class FlatNodeMap(object): else: self.__corr = (0, 1) if not self._hndl2index: - self._hndl2index = dict([key[1], index] + self._hndl2index = dict((key[1], index) for index, key in enumerate(self._index2hndl)) def real_path(self, index): @@ -398,14 +398,8 @@ class FlatNodeMap(object): insert_pos = bisect.bisect_left(self._index2hndl, srtkey_hndl) self._index2hndl.insert(insert_pos, srtkey_hndl) #make sure the index map is updated - if sys.version_info[0] < 3: # keep this, for speed in Python2 - for hndl, index in self._hndl2index.iteritems(): # in Python2 "if" - if index >= insert_pos: - self._hndl2index[hndl] += 1 - else: - for hndl, index in self._hndl2index.items(): - if index >= insert_pos: - self._hndl2index[hndl] += 1 + for srt_key,hndl in self._index2hndl[insert_pos+1:]: + self._hndl2index[hndl] += 1 self._hndl2index[srtkey_hndl[1]] = insert_pos #update self.__corr so it remains correct if self._reverse: @@ -447,14 +441,8 @@ class FlatNodeMap(object): if self._reverse: self.__corr = (len(self._index2hndl) - 1, -1) #update the handle2path map so it remains correct - if sys.version_info[0] < 3: # keep this, for speed in Python2 - for key, val in self._hndl2index.iteritems(): # in Python2 "if" - if val > index: - self._hndl2index[key] -= 1 - else: - for key, val in self._hndl2index.items(): - if val > index: - self._hndl2index[key] -= 1 + for srt_key,hndl in self._index2hndl[index:]: + self._hndl2index[hndl] -= 1 return Gtk.TreePath((delpath,)) #-------------------------------------------------------------------------