"Lloyd Zusman" <ljz / asfast.com> schrieb im Newsbeitrag news:m3y8kv2qx2.fsf / asfast.com... > First of all, I very much thank all of you who responded to my query. I've > read all of your useful and helpful replies, but I am only responding to > this final one, so as to minimize bandwidth. > > > "Robert Klemme" <bob.news / gmx.net> writes: > > > [ ... ] > > > > require 'benchmark' > > include Benchmark > > > > str = "Hammer and tongs" > > > > bm(7) do |x| > > x.report("1") { 100000.times { str.reverse.split(//).each { |ch| > > ch } } } > > x.report("2") { 100000.times { str.reverse.split('').each { |ch| > > ch } } } > > x.report("3") { 100000.times { str.reverse.each_byte { |ch| ch.chr } } } > > x.report("4") { 100000.times { (str.length-1).downto(0) {|idx| ch = > > str[idx]} } } > > x.report("5") { 100000.times { len = str.size; for idx in 1..len ; ch = > > str[len-idx] end } } > > end > > user system total real > > 1 6.828000 0.000000 6.828000 ( 6.907000) > > 2 6.891000 0.000000 6.891000 ( 6.936000) > > 3 5.078000 0.000000 5.078000 ( 5.098000) > > 4 2.281000 0.000000 2.281000 ( 2.287000) > > 5 3.391000 0.000000 3.391000 ( 3.395000) > > > I have been so steeped in Ruby-ish thinking that I had completely > forgotten about array indexing. Duh! :-) > And being so reminded, at first I would not have suspected that the > algorithms based on indexing would be faster than the others. But I > suspect that the absence of 'reverse' is what accounts for the speed > differences. The most costly operations are object creations (apart from Fixnums which AFAIK are handled a bit differently). From that it's clear that reverse.split is extremely costly since there are n + 2 instances created (1 Array, 1 reverse String, n Strings with length 1). > By the way, I tried this with longer strings: between 40 and 8192 bytes, > which are the most likely lengths for the strings I will be dealing > with. As the lengths increase beyond something like 50-60 bytes, > algorithm number 5 becomes faster than algorithm 4, and the difference > in speeds keeps increasing with longer strings. > > But if I replace "ch.chr" in algorithm 3 and with just "ch" by itself, > that algorithm suddenly becomes the fastest. Oh, that can happen if you just copy and past. Of course ".chr" must be removed in order to get comparable results. > The state machine to which > I want to feed the characters can deal with integer representations as > easily as their character equivalents. Note that there is no character type in Ruby: >> "foo"[0].class => Fixnum >> 77.chr.class => String >> > So, it looks like the following > would be the fastest for my purposes: > > string.reverse.each_byte { > |c| > feedToMyStateMachine(c) > } Yep. Regards robert #!/usr/bin/ruby require 'benchmark' include Benchmark str = "Hammer and tongs" bm(7) do |x| x.report("1") { 100000.times { str.reverse.split(//).each { |ch| ch } } } x.report("2") { 100000.times { str.reverse.split('').each { |ch| ch } } } x.report("3") { 100000.times { str.reverse.each_byte { |ch| ch } } } x.report("4") { 100000.times { (str.length-1).downto(0) {|idx| ch = str[idx]} } } x.report("5") { 100000.times { len = str.size; for idx in 1..len ; ch = str[len-idx] end } } end str = "Hammer and tongs" * 10 bm(7) do |x| x.report("1") { 100000.times { str.reverse.split(//).each { |ch| ch } } } x.report("2") { 100000.times { str.reverse.split('').each { |ch| ch } } } x.report("3") { 100000.times { str.reverse.each_byte { |ch| ch } } } x.report("4") { 100000.times { (str.length-1).downto(0) {|idx| ch = str[idx]} } } x.report("5") { 100000.times { len = str.size; for idx in 1..len ; ch = str[len-idx] end } } end 11:40:07 [ruby]: ./str-reverse.rb user system total real 1 6.828000 0.000000 6.828000 ( 6.864000) 2 6.937000 0.000000 6.937000 ( 6.926000) 3 1.375000 0.000000 1.375000 ( 1.384000) 4 2.282000 0.000000 2.282000 ( 2.279000) 5 3.422000 0.000000 3.422000 ( 3.412000) user system total real 1 59.906000 0.000000 59.906000 ( 60.014000) 2 60.250000 0.000000 60.250000 ( 60.420000) 3 10.625000 0.000000 10.625000 ( 10.626000) 4 21.687000 0.000000 21.687000 ( 21.714000) 5 22.422000 0.000000 22.422000 ( 22.455000)