月归档:八月 2008

用Benchmark测试不同ruby代码的运行速度

如果比较功能相同的几组代码的运行速度, 可以使用ruby语言里的Benchmark模块.
(开始前 设置中文环境, $KCODE = ‘u’)
比如, 连接两个字串, 如:
str1 = "中国"
str2 = "一定强!!!"

可以使用+
?> str1 + str2
=> "中国一定强!!!"
也可使用
>> "#{str1}#{str2}"
=> "中国一定强!!!"
还可以使用<<
>> str1 << str2
=> "中国一定强!!!"
(注意这种方法会改变str1的值,
>> str1
=> "中国一定强!!!")

如果想要知道这三种方法哪一个速度更快, 就可以使用Benchmark比较.
先定义三个不同的方法:

def joined_by_plus(str_a, str_b)
    500000.times do; str_a.dup + str_b; end
end

def joined_by_uniting(str_a, str_b)
    500000.times do; "#{str_a.dup}#{str_b}"; end
end

def joined_by_adding(str_a, str_b)
    500000.times do; str_a.dup << str_b; end
end

因为这三种方法速度都很快, 比较一次的时间很难分出上下, 所以每种方法都做500000次.
因为<< 会改变变量, 所以在第三个方法中使用了str_a.dup, 备份出一个str_a来测试, 其它二个方法虽然从理论上不须要这个dup, 但为了时间上的公平, 也给它们加上了.

下面是测试代码:
require ‘benchmark’

Benchmark.bmbm(10) do |t|
  t.report(‘加号连接’) { joined_by_plus(str1, str2) }
  t.report(‘放进引号’) { joined_by_uniting(str1, str2)}
  t.report(‘使用<<’) { joined_by_adding(str1, str2)}
end

bmbm是Benchmark的测试方法, 这是双重测试, 用来提高精确度. 里面参数10用来调节标签在结果里的显示占位宽度, 不对结果产生影响.
report(‘加号连接’)里的参数是为相应测试的标签名, 用来区别测试结果.

下面就是结果:

Rehearsal ————————————————
加号连接   1.800000   0.580000   2.380000 (  2.435614)
放进引号   2.080000   0.590000   2.670000 (  2.706669)
使用<<       2.000000   0.580000   2.580000 (  2.635540)
————————————— total: 7.630000sec

                   user     system      total        real
加号连接   1.810000   0.600000   2.410000 (  2.476613)
放进引号   2.050000   0.600000   2.650000 (  2.656080)
使用<<       1.960000   0.600000   2.560000 (  2.567434)

因为使用了bmbm方式, 所以会有两个结果, 第一个是演习结果, 第二个是真实结果.  如果使用bm方法, 将只会有一组结果.
结果有user时间, 系统时间, 总时间和实际花费的时间. 单位为秒.

从结果可以看出, 使用+连接两个字串时速度最快, 而放进引号的方法最慢. 不过从结果也可以看出即使进行500000执行的结果也相差在0.3秒之内, 平时换用问题不大.

看来不是这一次, 希望下次你在自己的Benchmark试验中, 会发现给你的程序带来巨大速度提供的代码.

发表在 Ruby on Rails | 留下评论

用ruby语言以句子为单位拆分一个字串

目标, 用ruby语言以句子为单位拆分一个字串. 如:
给出字串:
s="这是一个句子,另一个句子.一个新句子!难道这不是另一个句子吗?"
将它分拆为:
 ["这是一个句子,"], ["另一个句子."], ["一个新句子!"], ["难道这不是另一个句子吗?"]
样式.
测试前将ruby的$KCODE环境变量设置为’u', 启动UTF8编码支持中文.
$KCODE=’u’
尝试1:
>> s.split(/\.|,|\?|\!/)
=> ["这是一个句子", "另一个句子", "一个新句子", "难道这不是另一个句子吗"]
等同于:
>> s.split(/[.,!?]/)
=> ["这是一个句子", "另一个句子", "一个新句子", "难道这不是另一个句子吗"]
虽然分开了句子, 但失去了标点.

>> s.split(/([.,!?])/)
=> ["这是一个句子", ",", "另一个句子", ".", "一个新句子", "!", "难道这不是另一个句子吗", "?"]
用括号将正则组成一组, 标点出来了, 但和句子是分开的.

改用scan
>> s.scan /.+?[.,?!]/
=> ["这是一个句子,"], ["另一个句子."], ["一个新句子!"], ["难道这不是另一个句子吗?"]
成功了!!

如果一定要这样:
>> s.scan(/(.+?(\.|\?|\!))/).collect{|p|p[0]}
=> ["这是一个句子,另一个句子.", "一个新句子!", "难道这不是另一个句子吗?"]
也是可行的.

发表在 Ruby on Rails | 留下评论

svnX出错的解决办法

svnX是苹果上的svn图形管理软件, 下面是我总结的常见错误解决办法.
1.导入一个已经被SVN管理过的文件夹, 这时要先删除原有的svn记录:
到新移入目录的根目前执行:
find ./ -name ".svn" | xargs rm -Rf
2.用svnx删除一个文件夹出现 has no URL 错误.
手动用命令删除:
svn delete app/folder
svn commit -m ‘mission impossible’
3.覆盖文件后出现commit错误
先拿开那个文件或文件夹, 执行delete文件/文件夹操作, 然后放入新文件/文件夹, 执行add操作
4.ignore已经被收录的文件/文件夹
方法同上, 先移开这些文件/文件夹, 执行delete操作, 然后
svn propset svn:ignore "*" app/folder
svn commit -m ‘ignore!!!’
然后再移回旧文件.
另: 今天刚下载了苹果上的另一个svn管理工具Versions beta, 还没详细试用, 不清楚效果.

发表在 信息处理 | 一条评论

GPS

就在超市口的一个拐角, 他靠着绿化栏半躺在地上. 破破烂烂的衣服一块灰一块黑. 领域内摆着一个变形了的搪瓷碗. 碗里零星地散着几个硬币.
刚吃完午饭的他一边有节奏地上下晃着斜歪着的头, 一边哼着什么. 显然是那种很适合看女人大腿时哼着的东西.
苍蝇不时落在他的脚上. 他已经不对苍蝇动手了. 开始是讨厌, 然后他慢慢同情起这些飞虫起来, 认为这些虫子大概也样是无家可归的. 但, 现在这种同情也慢慢地淡漠了. 生活就是残酷的 — 也许这就是三天后他认为更成熟的想法…
三天了! 终于三天了… 他一边感觉到一种解脱, 同时竟也感觉到一种怀念…
就在这时, 突然传来一首"月亮之上". 是一条短信: "北, 200米, 光头".
他立马起身, 从身后掏出一手枪.
"他妈的北在哪里???"他愣了2秒, 但随即掏出一手机大小的设备, 中间是一个血红的大箭头, 箭头上方是四个斗大的汉字– "他妈的北"!

发表在 某时雨集 | 留下评论

感古都许昌

悠悠今日水
依依古灞陵
枭雄挥剑去
闲云却长停

发表在 某时雨集 | 留下评论