自己用到 ruby 的字符串连接的时候,从'str1 += str2'号改成'str1 << str2',感觉就像翻身农奴把歌唱一样,速度快了十倍,内存消耗小了约一半……
本来是联想到 c#的 Stringbuilder,然后上 stackoverflow 看看 ruby 连接字符串时被吐槽的地方,看到了'<<'号,就试一试,效果很好。因为懒得打字,所以我写 Array.push(obj)都改成 Array << obj 的形式了。
又找到了个比较详细的解释: https://www.xuebuyuan.com/1256522.html
某些新手教程不深入讲字符串连接。
1
memedahui 2019-12-14 14:20:29 +08:00
快忘光了,随手翻翻手中的汇编指南
|
2
nulIptr 2019-12-14 14:38:24 +08:00 via iPhone
不要一刀切,很多时候直接用+可以被编译期优化掉,尤其是拼 sql 的时候
|
3
dbpe 2019-12-14 14:40:41 +08:00
emmmm..这些不是应该能被编译器优化掉么....
|
4
Bromine0x23 2019-12-14 15:04:52 +08:00
再本质点的话是因为 a += b 只是 a = a + b 缩写,也就是没有修改原本的 a 对象,而是用生成的新对象替换了 a 的引用
|
5
Raymon111111 2019-12-14 15:15:49 +08:00
既然大多数人都用 str1+str2 这种写法, 而且这种写法看起来简洁直观, 那编译器应该对它进行优化
(就和 java 一样, 单纯的字符串拼接加号是最快的, 除了放在循环里 |
6
maomaomao001 2019-12-14 15:49:00 +08:00 via Android
如此简单的事情,居然编译器不能优化? 居然还要手动自己调 ? 应该不会吧
|
7
agagega 2019-12-14 16:52:32 +08:00 via iPhone
Ruby 现在不都 Rope 了么?而且这种机会应该可以被优化掉了
|
9
crella OP @Bromine0x23 你一说我才想起。
比如 a=1; 10.times {a += 1;}; a.object_id =>23 已知 1.object_id = 3,2.object_id = 5,则 23=10*2+3。 真是让人觉得奇怪。 |
10
crella OP 顺便做个笔记吧。
a=5; a.object_id == 5.object_id => true ObjectSpace._id2ref(a.object_id) == 5 => true |
11
Bromine0x23 2019-12-14 19:22:02 +08:00
@crella 没什么奇怪的,对象 ID 空间就是这么规定的 https://github.com/ruby/ruby/blob/v2_6_5/gc.c#L3258
|
13
crella OP |
14
msg7086 2019-12-15 07:56:45 +08:00 1
顺便一提,原本 Matz 是打算在 Ruby 3 里默认冻结字符串常量的,所以当你在旧版本里开启 frozen_string_literal 提前享受这份快乐的时候,是不能对字符串做 << 操作的。不过后来 Matz 后悔了,于是 Ruby 3 不打算默认冻结了……
另外各方面都比较好的做法是用数组做 StringBuilder,即 c = ['start'] 10000.times { c << "-con" } c = c.join 这种做法在没开 frozen string 的时候用时只比<<慢 60%,开了 frozen 以后比<<快 5%,比插值和+=都快得多。 |
15
yannxia 2019-12-15 09:50:18 +08:00
以前 JavaBoy 也经常有这样的困扰。
|