一个网络工程师对"高薪"的叙述
2010-08-06 23:58
176 查看
理解Ruby中的标志(Understanding Ruby Symbols)
原文出处:http://glu.ttono.us/articles/2005/08/19/understanding-ruby-symbols
翻译:Suninny AT Gmail.com
标志在Ruby中是一个迷。我们用她,但多数人并不真正懂她。
什么是标志?
简单来说,标志是你用来代表名字或字符串的一个东西。这可以归结为一种高效的描述名--产生单一的字符串用于每个命名实例,这样就节省了空间。
琼斯博士的案例
琼斯博士(Dr Jones)是个心理学家。 他通常使用语词联想试验诊断患者,并且使用Ruby记录一切。 他的第一名患者Why来到了这里:
Dr J: Red
Why : Ruby
Dr J: Transportation
Why : Rails
Dr J: Chunky
Why : Bacon
琼斯博士建立一个散列来存储这些数据:
why = {”red” => “ruby”, “transportation” => “rails”, “chunky” => “bacon”}
问题所在
在进行几百个语词联想试验之后,琼斯博士开始意识到他用尽了内存! 于是琼斯在irb进行测试:
> patient1 = { “ruby” => “red” }
> patient2 = { “ruby” => “programming” }
> patient1.each_key {|key| puts key.object_id.to_s}
211006
> patient2.each_key {|key| puts key.object_id.to_s}
203536
我们看到,每次他建立一个散列来存储信息,Ruby就在不同的内存位置为每个键建立了一个新的字符串对象。
幸运的是,我们还有其他的方法。
用标志来突围
不同于字符串,在一个Ruby会话期间,同一个名称的标志只作一次初始化然后就存在于内存中。当你需要重用字符串来表示其他东西时,标志是再适合不过的了。重做琼斯博士的测试,我们能直接观察到:
> patient1 = { :ruby => “red” }
> patient2 = { :ruby => “programming” }
> patient1.each_key {|key| puts key.object_id.to_s}
3918094
> patient2.each_key {|key| puts key.object_id.to_s}
3918094
通过使用标志,在语词联想试验中我们用单一的内存地址代表了“ruby”这个单词。随着时间的推移,这能节省下大量的空间。
标志的其他应用场合
无论何时,只要你是重用一个单词来反复代表其他东西,标志就能派上用场。不管是散列中的一个键,还是Http查询中的一个方法。在最新、最伟大的Web框架--Ruby on Rails的路由和链接中就应用到了标志。
在表现一个网页之前,Rails会执行框架内部的控制器(controllers)中定义的动作(actions),因此在Rails中,链接就像这样表示:
link_to(”View Article”, :controller => “articles”, :action => “show”, :id => 1)
当一个应用可能至少有数百个链接,或者说有数百个不同动作和控制器的引用时,使用标志就比使用字符串高效得多。
最后,值得注意的是标志的应用场合并不局限于散列中的键。例如,如果你写一个Http客户端(或服务器),在这个程序中,可能需要多次用到get和post:
do_this if query == :get
…
send_message_to_server(:post,filename)
当需要反复用到一个字符串时,标志或许是一个蛮不错的替代品。
更新
在Freenode(译注:一个著名的IRC服务器)的ruby-lang频道,Aria和Nome为这篇文章给出了有用的增补。
11:58 < Aria> 同样,即便完全出于现实方面的考虑,使用标志也很理想:如果你要引用一个方法名,就用标志吧,因为她总会在那里(在定义了方法之后)。
12:03 < nome> Kevin Clark:标志的目的是用来辨别构造(主要是用户级的):散列中的槽、一个方法、一个选项等等。
同样,Aria还回应了Geoff在注解中提出的问题:
Geoff:我很想知道1000个字符串”red”究竟要比:red耗费多少内存。记住,在Rails之外,”red” != :red
Aria:多少内存?20字节/对象,加上存储数据的3个字节,再加上存储长度的4个字节,一共是27×1000=27000个字节。与此相对,标志表条目的一份拷贝,只需几个字节。
Jim Weirich 写到:
我通常有下面的法则来比较字符串和标志:
(1) 如果侧重于对象的内容(即字符序列),就用字符串;
(2) 如果侧重于对象的身份,就用标志。
原文出处:http://glu.ttono.us/articles/2005/08/19/understanding-ruby-symbols
翻译:Suninny AT Gmail.com
标志在Ruby中是一个迷。我们用她,但多数人并不真正懂她。
什么是标志?
简单来说,标志是你用来代表名字或字符串的一个东西。这可以归结为一种高效的描述名--产生单一的字符串用于每个命名实例,这样就节省了空间。
琼斯博士的案例
琼斯博士(Dr Jones)是个心理学家。 他通常使用语词联想试验诊断患者,并且使用Ruby记录一切。 他的第一名患者Why来到了这里:
Dr J: Red
Why : Ruby
Dr J: Transportation
Why : Rails
Dr J: Chunky
Why : Bacon
琼斯博士建立一个散列来存储这些数据:
why = {”red” => “ruby”, “transportation” => “rails”, “chunky” => “bacon”}
问题所在
在进行几百个语词联想试验之后,琼斯博士开始意识到他用尽了内存! 于是琼斯在irb进行测试:
> patient1 = { “ruby” => “red” }
> patient2 = { “ruby” => “programming” }
> patient1.each_key {|key| puts key.object_id.to_s}
211006
> patient2.each_key {|key| puts key.object_id.to_s}
203536
我们看到,每次他建立一个散列来存储信息,Ruby就在不同的内存位置为每个键建立了一个新的字符串对象。
幸运的是,我们还有其他的方法。
用标志来突围
不同于字符串,在一个Ruby会话期间,同一个名称的标志只作一次初始化然后就存在于内存中。当你需要重用字符串来表示其他东西时,标志是再适合不过的了。重做琼斯博士的测试,我们能直接观察到:
> patient1 = { :ruby => “red” }
> patient2 = { :ruby => “programming” }
> patient1.each_key {|key| puts key.object_id.to_s}
3918094
> patient2.each_key {|key| puts key.object_id.to_s}
3918094
通过使用标志,在语词联想试验中我们用单一的内存地址代表了“ruby”这个单词。随着时间的推移,这能节省下大量的空间。
标志的其他应用场合
无论何时,只要你是重用一个单词来反复代表其他东西,标志就能派上用场。不管是散列中的一个键,还是Http查询中的一个方法。在最新、最伟大的Web框架--Ruby on Rails的路由和链接中就应用到了标志。
在表现一个网页之前,Rails会执行框架内部的控制器(controllers)中定义的动作(actions),因此在Rails中,链接就像这样表示:
link_to(”View Article”, :controller => “articles”, :action => “show”, :id => 1)
当一个应用可能至少有数百个链接,或者说有数百个不同动作和控制器的引用时,使用标志就比使用字符串高效得多。
最后,值得注意的是标志的应用场合并不局限于散列中的键。例如,如果你写一个Http客户端(或服务器),在这个程序中,可能需要多次用到get和post:
do_this if query == :get
…
send_message_to_server(:post,filename)
当需要反复用到一个字符串时,标志或许是一个蛮不错的替代品。
更新
在Freenode(译注:一个著名的IRC服务器)的ruby-lang频道,Aria和Nome为这篇文章给出了有用的增补。
11:58 < Aria> 同样,即便完全出于现实方面的考虑,使用标志也很理想:如果你要引用一个方法名,就用标志吧,因为她总会在那里(在定义了方法之后)。
12:03 < nome> Kevin Clark:标志的目的是用来辨别构造(主要是用户级的):散列中的槽、一个方法、一个选项等等。
同样,Aria还回应了Geoff在注解中提出的问题:
Geoff:我很想知道1000个字符串”red”究竟要比:red耗费多少内存。记住,在Rails之外,”red” != :red
Aria:多少内存?20字节/对象,加上存储数据的3个字节,再加上存储长度的4个字节,一共是27×1000=27000个字节。与此相对,标志表条目的一份拷贝,只需几个字节。
Jim Weirich 写到:
我通常有下面的法则来比较字符串和标志:
(1) 如果侧重于对象的内容(即字符序列),就用字符串;
(2) 如果侧重于对象的身份,就用标志。
相关文章推荐
- 一个网络工程师对"高薪"的叙述
- 一个网络工程师对"高薪"的叙述
- 一个网络工程师对"高薪"的叙述
- "狗日"的格力——记录一个屌丝消费者与世界500强格力的战斗史
- 题目:一个数如果恰好等于它的因子之和,这个数就称为 "完数 "。例如6=1+2+3.编程 找出1000以内的所有完数。(java)
- 关于"干货集中营"的一个开源App
- 请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配
- UserControl 的一个值得注意的问题 [属性" * "的代码生成失败.错误是:"程序集"*.Version=1.0.0.0,Culture=neutral,..........无标记为序列化"
- 展望明年的高级网络工程师-"网络规划设计师"
- GC是如何判断一个对象为"垃圾"的?被GC判断为"垃圾"的对象一定会被回收吗?
- 对"该字符串未被识别为有效的 DateTime。有一个从索引 8 处开始的未知字"的异常处理
- 网上有关"回车"和"换行"的一个有趣说法
- 使用LinqDataSource出现“找不到与ViewState中存储的原始值中的给定键相匹配的行,请确保"keys"字典包含与上一个Select操作返回的行对应的唯一键值”错误的解决办法
- 发现 ASP.Net 的一个关于"回车提交"的 Bug ? 必须多于一个 Text 域"回车提交",Server: ButtonX_Click 才能截获!
- 打印出所有的 "水仙花数 ",所谓 "水仙花数 "是指一个三位数,其各位数字立方和等于该数本身。例如:153是一个 "水仙花数 ",因为153=1的三次方+5的三次方+3的三次方。
- 给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
- 请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字
- 关于"干货集中营"的一个开源App
- 写一个函数判断字符串中"{"与"}","["与"]","("与")"匹配,"{"必须在"}"前面,"["必须在"]"前面,"("必须在")"前面,可以嵌套
- 在linux上使用"scp"命令拷贝一个目录到另一台服务器的时候报"not a regular file"错误的解决办法