From: "mame (Yusuke Endoh)" Date: 2013-11-17T03:28:50+09:00 Subject: [ruby-core:58382] [ruby-trunk - Feature #9118] In Enumerable#to_a, use size to set array capa when possible Issue #9118 has been updated by mame (Yusuke Endoh). I think the proposal will break the compatibility of the following code: class C include Enumerable def size to_a.size end def each end end C.new.size #=> expected: 0, with the proposal: stack level too deep Examples in the wild: * https://github.com/andreasronge/neo4j/blob/c421fb883d9de4748ef431bda9973959dda2a45c/lib/neo4j/traversal/traverser.rb#L196 * https://github.com/ActiveRDF/ActiveRDF/blob/master/lib/active_rdf/model/property.rb#L290 * https://bitbucket.org/Bounga/tooltips/src/925ccaa9e5a6/lib/pdoc/pdoc/parser/documentation_nodes.rb#cl-100 * http://pastebin.com/2Sr0UXQZ In addition, #each and #size does not necessarily have a common semantics. In fact, IO#each yields strings in lines, but IO#size returns a count in bytes. -- Yusuke Endoh ---------------------------------------- Feature #9118: In Enumerable#to_a, use size to set array capa when possible https://bugs.ruby-lang.org/issues/9118#change-42979 Author: HonoreDB (Aaron Weiner) Status: Open Priority: Normal Assignee: Category: Target version: Cross-post from https://github.com/ruby/ruby/pull/444. Enumerable#to_a works by creating an empty array with small capacity, then populating it and expanding the capacity as it goes. For large enumerables, this causes several resizes, which can hurt performance. When an enumerable exposes a size method, we can guess that the resulting array's size will usually be equal to the enumerable's size. If we're right, we only have to set capacity once, and if we're wrong, we don't lose anything. The attached file (or linked PR) adjusts enum.c's to_a method to take advantage of the size method when it's there. In my tests this makes Range#to_a about 10% faster, and doesn't have any significant effect on a vanilla enum with no size method. I couldn't find any existing benchmark that this consistently made better or worse. If you like this idea, this could also be done in other classes with custom to_a, like Hash. -- http://bugs.ruby-lang.org/