I am trying to globally replace characters in a string by “chaining” the
String#gsub method like so:
str = “count=(a+b); if(a<=b) d[i]=10;f(a,b)“
puts str.gsub(/,/,’ , ‘).gsub(/(/,’ ( ‘).gsub(/)/,’ )
’).gsub(/([^<>])=/,’\1 = ').gsub(/;/,”;\n”)
Is there a better (faster) way to do this ?
Here is how I want the replacement to work:
‘;’ — to be replaced by --> ‘;\n’ new line after
’,’ ------------------------> ’ , ’ single space on either side
’(’ ------------------------> ’ ( ’ single space on either side
’)’ ------------------------> ’ ) ’ single space on either side
’=’ ------------------------> ’ = ’ single space on either side except when
preceded by < or >
I am using ruby 1.7.3 (2002-11-17) [i386-mswin32]
TIA,
-shanko
For your need, the chained gsub is the fasted I can think of. Here’s my
comparison against two solutions involving the block form of gsub.
I’m using ruby 1.7.3 (2002-11-27) [i586-linux].
require ‘benchmark’
include Benchmark
n = 1000
str = “count=(a+b); if(a<=b) d[i]=10;f(a,b)”
test = nil
bm do |x|
x.report( “chained gsubs:” ) do
n.times do
test = str.gsub(/,/,’ , ‘).gsub(/(/,’ ( ‘).gsub(/)/,’ ) ‘).gsub(/([^<>])=/,’\1 = ').gsub(/;/,“;\n”)
end
# puts
# p test
end
x.report( “grouped gsub:” ) do
n.times do
test = str.gsub( /(?:(,|(|)|[^<>]=)|(;))/ ) do
if $1
"#{ $1[0…-2] } #{ $1[-1,1] } "
else
“#{ $2 }\n”
end
end
end
# puts
# p test
end
x.report( “gsub and case:” ) do
n.times do
test = str.gsub( /[,();]|[^<>]=/ ) do |m|
case m
when /=$/
"#{ $` } = "
when /;/
“;\n”
else
" #{ m } "
end
end
end
# puts
# p test
end
end
Benchmark results:
user system total real
chained gsubs: 0.830000 0.000000 0.830000 ( 0.831508)
grouped gsub: 2.020000 0.000000 2.020000 ( 2.022475)
gsub and case: 1.270000 0.000000 1.270000 ( 1.277238)
_why
···
Shashank Date (sdate@kc.rr.com) wrote:
I am trying to globally replace characters in a string by “chaining” the
String#gsub method like so:
str = “count=(a+b); if(a<=b) d[i]=10;f(a,b)”
puts str.gsub(/,/,’ , ‘).gsub(/(/,’ ( ‘).gsub(/)/,’ )
‘).gsub(/([^<>])=/,’\1 = ').gsub(/;/,“;\n”)
Is there a better (faster) way to do this ?
Hi,
n = 1000
str = “count=(a+b); if(a<=b) d[i]=10;f(a,b)”
test = nil
bm do |x|
x.report( “chained gsubs:” ) do
n.times do
test = str.gsub(/,/,’ , ‘).gsub(/(/,’ ( ‘).gsub(/)/,’ ) ‘).gsub(/([^<>])=/,’\1 = ‘).gsub(/;/,“;\n”)
end
# puts
# p test
end
x.report( “chained gsubs 2:” ) do
n.times do
test = str.gsub(/[,()]/,’ & ‘).gsub(/([^<>])=/,’\1 = ').gsub(/;/,“;\n”)
end
# puts
# p test
end
With 10,000 iterations:
user system total real
chained gsubs: 2.270000 0.020000 2.290000 ( 2.306303)
chained gsubs 2: 2.030000 0.040000 2.070000 ( 2.066607)
grouped gsub: 5.570000 0.060000 5.630000 ( 5.758734)
gsub and case: 3.720000 0.070000 3.790000 ( 3.950212)
···
At Wed, 11 Dec 2002 14:58:28 +0900, why the lucky stiff wrote:
–
Nobu Nakada
x.report( “chained gsubs 3:” ) do
n.times do
test = str.gsub(/[,()]/,’ & ‘).gsub!(/([^<>])=/,’\1 = ').gsub!(/;/,“;\n”)
end
# puts
# p test
end
With 100,000 iterations:
user system total real
chained gsubs: 6.270000 0.020000 6.290000 ( 6.389039)
chained gsubs 2: 5.760000 0.020000 5.780000 ( 5.808392)
chained gsubs 3: 5.620000 0.000000 5.620000 ( 5.703204)
grouped gsub: 19.880000 0.020000 19.900000 ( 20.185286)
gsub and case: 12.580000 0.020000 12.600000 ( 12.791412)
···
On Wed, Dec 11, 2002 at 03:18:05PM +0900, nobu.nokada@softhome.net wrote:
Hi,
At Wed, 11 Dec 2002 14:58:28 +0900, > why the lucky stiff wrote:
n = 1000
str = “count=(a+b); if(a<=b) d[i]=10;f(a,b)”
test = nil
bm do |x|
x.report( “chained gsubs:” ) do
n.times do
test = str.gsub(/,/,’ , ‘).gsub(/(/,’ ( ‘).gsub(/)/,’ ) ‘).gsub(/([^<>])=/,’\1 = ‘).gsub(/;/,“;\n”)
end
# puts
# p test
end
x.report( “chained gsubs 2:” ) do
n.times do
test = str.gsub(/[,()]/,’ & ‘).gsub(/([^<>])=/,’\1 = ').gsub(/;/,“;\n”)
end
# puts
# p test
end
With 10,000 iterations:
user system total real
chained gsubs: 2.270000 0.020000 2.290000 ( 2.306303)
chained gsubs 2: 2.030000 0.040000 2.070000 ( 2.066607)
grouped gsub: 5.570000 0.060000 5.630000 ( 5.758734)
gsub and case: 3.720000 0.070000 3.790000 ( 3.950212)
–
_ _
__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_
_ \ / ` | ’ \
) | (| | |__ \ | | | | | (| | | | |
.__/ _,|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com
/*
*/
– from Linux kernel pre-2.1.91-1