Mercurial > hg
comparison mercurial/smartset.py @ 31015:1076f7eba964
smartset: convert set to list lazily
If the caller only wants to construct a baseset via a set, and then do
"__contains__" tests. It's unnecessary to initialize the list.
Testing on my unfiltered hg-committed repo where len(draft()) is 2600, this
patch shows about 6% improvement on set intensive queries:
Before:
$ for i in `seq 5`; hg perfrevset 'draft() & draft() & draft() & draft()'
! wall 0.001196 comb 0.000000 user 0.000000 sys 0.000000 (best of 2011)
! wall 0.001191 comb 0.000000 user 0.000000 sys 0.000000 (best of 2099)
! wall 0.001186 comb 0.010000 user 0.010000 sys 0.000000 (best of 1953)
! wall 0.001182 comb 0.000000 user 0.000000 sys 0.000000 (best of 2135)
! wall 0.001193 comb 0.000000 user 0.000000 sys 0.000000 (best of 2177)
After:
$ for i in `seq 5`; hg perfrevset 'draft() & draft() & draft() & draft()'
! wall 0.001128 comb 0.000000 user 0.000000 sys 0.000000 (best of 2247)
! wall 0.001119 comb 0.000000 user 0.000000 sys 0.000000 (best of 2317)
! wall 0.001115 comb 0.000000 user 0.000000 sys 0.000000 (best of 2244)
! wall 0.001131 comb 0.000000 user 0.000000 sys 0.000000 (best of 2093)
! wall 0.001124 comb 0.000000 user 0.000000 sys 0.000000 (best of 2134)
It could have bigger impact on larger sets in theory.
author | Jun Wu <quark@fb.com> |
---|---|
date | Fri, 17 Feb 2017 20:59:29 -0800 |
parents | 1be65deb3d54 |
children | 74f77f1c2215 |
comparison
equal
deleted
inserted
replaced
31014:219629d42786 | 31015:1076f7eba964 |
---|---|
169 if not isinstance(data, list): | 169 if not isinstance(data, list): |
170 if isinstance(data, set): | 170 if isinstance(data, set): |
171 self._set = data | 171 self._set = data |
172 # set has no order we pick one for stability purpose | 172 # set has no order we pick one for stability purpose |
173 self._ascending = True | 173 self._ascending = True |
174 data = list(data) | 174 # converting set to list has a cost, do it lazily |
175 self._list = data | 175 data = None |
176 else: | |
177 data = list(data) | |
178 if data is not None: | |
179 self._list = data | |
176 self._datarepr = datarepr | 180 self._datarepr = datarepr |
177 | 181 |
178 @util.propertycache | 182 @util.propertycache |
179 def _set(self): | 183 def _set(self): |
180 return set(self._list) | 184 return set(self._list) |
183 def _asclist(self): | 187 def _asclist(self): |
184 asclist = self._list[:] | 188 asclist = self._list[:] |
185 asclist.sort() | 189 asclist.sort() |
186 return asclist | 190 return asclist |
187 | 191 |
192 @util.propertycache | |
193 def _list(self): | |
194 # _list is only lazily constructed if we have _set | |
195 assert '_set' in self.__dict__ | |
196 return list(self._set) | |
197 | |
188 def __iter__(self): | 198 def __iter__(self): |
189 if self._ascending is None: | 199 if self._ascending is None: |
190 return iter(self._list) | 200 return iter(self._list) |
191 elif self._ascending: | 201 elif self._ascending: |
192 return iter(self._asclist) | 202 return iter(self._asclist) |
202 @util.propertycache | 212 @util.propertycache |
203 def __contains__(self): | 213 def __contains__(self): |
204 return self._set.__contains__ | 214 return self._set.__contains__ |
205 | 215 |
206 def __nonzero__(self): | 216 def __nonzero__(self): |
207 return bool(self._list) | 217 return bool(len(self)) |
208 | 218 |
209 def sort(self, reverse=False): | 219 def sort(self, reverse=False): |
210 self._ascending = not bool(reverse) | 220 self._ascending = not bool(reverse) |
211 self._istopo = False | 221 self._istopo = False |
212 | 222 |
216 else: | 226 else: |
217 self._ascending = not self._ascending | 227 self._ascending = not self._ascending |
218 self._istopo = False | 228 self._istopo = False |
219 | 229 |
220 def __len__(self): | 230 def __len__(self): |
221 return len(self._list) | 231 if '_list' in self.__dict__: |
232 return len(self._list) | |
233 else: | |
234 return len(self._set) | |
222 | 235 |
223 def isascending(self): | 236 def isascending(self): |
224 """Returns True if the collection is ascending order, False if not. | 237 """Returns True if the collection is ascending order, False if not. |
225 | 238 |
226 This is part of the mandatory API for smartset.""" | 239 This is part of the mandatory API for smartset.""" |