From: Ardanwen Date: 2004-12-17T00:37:14+09:00 Subject: Re: String.scan - catching overlapping patterns with lookahead First time trying to use ruby's benchmark module. Doing something wrong, ---------- boris:falcon:~/SPEC:ruby bench-search.rb user system total real ../benchmark.rb:148:in `times': undefined method `times' for Process:Module (NameError) ---------- so I switched back to linux's "time bench-search.rb". Re-rewrote your program to something that resembles mine more again, and then they're similarly slow again (n=50000). boris:falcon:~/SPEC:time bench-search.rb 7.430u 0.060s 0:07.99 93.7% 0+0k 0+0io 359pf+0w (david) boris:falcon:~/SPEC:time bench-search.rb 7.480u 0.010s 0:07.54 99.3% 0+0k 0+0io 348pf+0w (boris) Not sure why you find something so different. Gutfeeling says it might be because of your search size (3 chars instead of 5 chars, or the specific search- and searched-string you use. Doing some testing right now (n = 50000 though). Now with a 5char nonchanging pattern, changing searched-string [syntax: program pattern randomseed] boris:falcon:~/SPEC:time boris.rb 11111 1 8.210u 0.140s 0:08.43 99.0% boris:falcon:~/SPEC:time boris.rb 11111 1 8.320u 0.100s 0:08.57 98.2% boris:falcon:~/SPEC:time boris.rb 11111 2 7.920u 0.030s 0:07.98 99.6% boris:falcon:~/SPEC:time boris.rb 11111 2 7.980u 0.020s 0:07.99 100.1% boris:falcon:~/SPEC:time boris.rb 11111 3 4.760u 0.010s 0:04.77 100.0% boris:falcon:~/SPEC:time boris.rb 11111 3 4.770u 0.020s 0:04.82 99.3% boris:falcon:~/SPEC:time david.rb 11111 1 7.780u 0.000s 0:07.79 99.8% boris:falcon:~/SPEC:time david.rb 11111 1 7.840u 0.000s 0:07.91 99.1% boris:falcon:~/SPEC:time david.rb 11111 2 7.530u 0.000s 0:07.58 99.3% boris:falcon:~/SPEC:time david.rb 11111 2 7.440u 0.000s 0:07.51 99.0% boris:falcon:~/SPEC:time david.rb 11111 3 5.450u 0.000s 0:05.42 100.5% boris:falcon:~/SPEC:time david.rb 11111 3 5.510u 0.000s 0:05.60 98.3% Seems like searched-string pattern matters. Now look at search-string. Specific search string you use matters quite a lot. boris:falcon:~/SPEC:time boris.rb 10101 1 9.520u 0.000s 0:09.52 100.0% boris:falcon:~/SPEC:time boris.rb 10101 2 9.290u 0.010s 0:09.24 100.6% boris:falcon:~/SPEC:time boris.rb 10101 3 8.620u 0.030s 0:08.70 99.4% boris:falcon:~/SPEC:time david.rb 10101 1 9.420u 0.000s 0:09.51 99.0% boris:falcon:~/SPEC:time david.rb 10101 2 8.710u 0.000s 0:08.78 99.2% boris:falcon:~/SPEC:time david.rb 10101 3 8.540u 0.010s 0:08.79 97.2% So not sure if that's enough to explain the difference between 1's and 0's and banana's. Another factor is the size of the search string, but I grow a bit weary of testing :). Anyway, thanks for testing. Time to look at that search-string link. bench-search.rb ---------------------------------------- #! /usr/bin/env ruby FIVE = ["00000","00001","00010","00011","00100","00101","00110","00111","01000","01001","01010","01011","01100","01101","01110","01111","10000","10001","10010","10011","10100","10101","10110","10111","11000","11001","11010","11011","11100","11101","11110","11111"] str = "" begin str << "#{rand(2)}" end until str.length == 1000 srand(1) n = 50000 def boris(str) pattern = FIVE[rand(32)] c = 0 i = 1000 begin i = str[0,i + 4].rindex(pattern) c += 1 if i != nil end until i == nil c end def david(str) pattern = FIVE[rand(32)] str.scan(/(?=#{pattern})/).size end n.times { boris(str) } #n.times { david(str) } ----------------------------------------- boris.rb ------------------------ #! /usr/bin/env ruby # This bit makes a string length 1000 filled with random 0's and 1's srand(ARGV[1].to_i) str = "" begin str << "#{rand(2)}" end until str.length == 1000 # This is the method. def boris(str) c = 0 i = 1000 begin i = str[0,i + 4].rindex(ARGV[0]) c += 1 if i != nil end until i == nil c end # Here we run it. 50000.times { boris(str) } -------------------------- david.rb ------------ #! /usr/bin/env ruby # This bit makes a string length 1000 filled with random 0's and 1's srand(ARGV[1].to_i) str = "" begin str << "#{rand(2)}" end until str.length == 1000 # This is the method. def david(str) str.scan(/(?=#{ARGV[0]})/).size end # Here we run it. 50000.times { david(str) } ---------------------