From: George Ogata Date: 2004-09-05T21:50:14+09:00 Subject: Re: autochomp? "Robert Klemme" writes: > "Kristof Bastiaensen" schrieb im Newsbeitrag > news:pan.2004.09.03.22.50.31.89211@vleeuwen.org... >> Hi, >> >> On Fri, 03 Sep 2004 18:03:35 +0200, Robert Klemme wrote: >> >> > >> > "Kristof Bastiaensen" schrieb im Newsbeitrag >> > news:pan.2004.09.02.20.13.44.101750@vleeuwen.org... >> >> Hi, >> >> >> >> On Thu, 02 Sep 2004 19:18:10 +0200, Robert Klemme wrote: >> >> >> >> >> >> > "Martin DeMello" schrieb im Newsbeitrag >> >> > news:idIZc.301315$J06.4478@pd7tw2no... >> >> >> [quoted text muted] >> >> > >> >> > Not AFAIK. You can do >> >> > >> >> > content = IO.readlines(file).each {|l| l.chomp!} >> >> > >> >> > or (more efficient) >> >> > >> >> > content = File.open(file) {|io| io.inject([]) {|ar,line| line.chomp!; >> >> > ar << line} } >> >> > >> >> > >> >> I think in this case the first is more efficient than the second. Since >> >> chomp! modifies the object inplace, no object gets created. >> > >> > ??? Please read again. The first is less efficient because it iterates >> > through the lines of the file twice and both use inplace modification >> > (#chomp!). >> > >> > Kind regards >> > >> > robert >> >> It would seem logical, but benchmarking shows different: >> >> #---- begin filetest.rb ---- >> require 'benchmark' >> >> file = "testfile.txt" >> Benchmark.bm(7) do |x| >> x.report("readlines:") do >> IO.readlines(file).each {|l| l.chomp!} >> end >> >> x.report("inject:") do >> File.open(file) {|io| io.inject([]) { >> |ar,line| line.chomp!; ar << line}} >> end >> >> x.report("foreach:") do >> IO.foreach(file){|line| (lines||=[]) << line.chomp!} >> end >> end >> #---- end filetest.rb ----- >> >> $ seq 10000 > testfile.txt >> $ ruby filetest.rb >> readlines: 0.050000 0.010000 0.060000 ( 0.085483) >> inject: 0.130000 0.010000 0.140000 ( 0.172144) >> foreach: 0.080000 0.000000 0.080000 ( 0.112690) > > That's really interesting. Did you also test with a real world file (a file > with longer lines presumably)? Interestingly enough, changing the block of > #inject does make it nearly as fast as readlines: What's the interesting bit? "readlines" is probably quicker than "inject" since there are less method calls. In "inject" and "foreach" (and "inject2" and "foreach2" in your later post), there are two method calls in the block: chomp! and <<. In "readlines" there's only 1. All that pushing and popping of ruby stack frames, method name looking up... it all adds up, more so, evidently, than walking the array an extra time. (Also note that "foreach" won't work right if chomp! returns nil, which it will on the last line if there's no newline @ EOF.)