[swift-dev] [swift-users] Collection underestimatedCount() does _?

Brent Royal-Gordon brent at architechies.com
Sat Mar 19 17:43:34 CDT 2016


> You gave cases for which `underestimatedCount()` is used:
>> For sequences with easily-calculated counts, this should give us a size that's just right. For sequences where they can kind of estimate the right count (for instance, if you're decoding a fixed-size buffer of UTF-8 bytes, and you know how many bytes there are but not exactly how many characters they'll decode to), it will get us at least part of the way there. For sequences whose size is completely unknown, it won't help but it won't hurt much either.
> 
> CC’ing swift-dev, I’m wondering:
> Was there a reason `underestimatedCount()` was chosen for Sequence instead of `estimatedCount()`. I suppose an overestimate would be bad for iterating `0..<estimatedCount()`, but I couldn’t find any existing loops over `0..<underestimatedCount()`.
> 
> Does anything depend on an underestimate of Sequence count? And if not, would it be better to be less restrictive when asking a Sequence for a size estimate?
> Since the exact count is returned for collections, the name also isn’t very precise.

Actually, the code samples I gave you *do* subtly depend on underestimatedCount being an underestimate, because the initial fast loop force-unwraps the element returned by `next`. If the count is an overestimate, that force unwrap will fail. You can see it in my example:

			// Load all the fast elements
			for _ in 0..<fastCount {
				let elem = generator.next()!
				_appendElementQuicklyBecauseWeAlreadyKnowWeHaveTheCapacity(elem)
			}

And in the actual standard library code:

	  // Add elements up to the initial capacity without checking for regrowth.
	  for _ in 0..<initialCapacity {
	    builder.addWithExistingCapacity(generator.next()!)
	  }

These and similar constructs could be turned into `if let`s, but that would add a conditional branch which would make the loop slower, particularly in -Ounchecked mode where safety checks are disabled. In that mode, the force unwrap operator simply *assumes* the value is not `nil`, which makes this code run as fast as possible—it pretty much can just copy or retain the element, assign it into the next slot in the array, and increment the array's count.

-- 
Brent Royal-Gordon
Architechies



More information about the swift-dev mailing list