Make crystal work and fast on string concatenation.

262 views
Skip to first unread message

Jin Qian

unread,
Aug 11, 2018, 10:14:29 AM8/11/18
to Crystal

Trying to write a performance related app with ruby. This app does a lot of string concatenation.  Was excited when I heard from my colleague that crystal-lang has the same syntax.

Wrote the following little snippet to test out performance of string concatenation.  It runs fine and fast with ruby, but crystall gave error 

Error in te3.rb:6: undefined method '<<' for String

 x << "1"


x = "jin"
start = Time.now
i = 0
while i < 200000
x << "1"
i += 1
end
puts (Time.now-start)
puts (x.length)

Note that in the above snippet, I can't use something like  x += "1",    which runs fine, but seriously impacted the performance:  with x << "1"  it took 0.04 seconds, with x += "1",  it took 3 seconds on my core i7.

Wonder if any one knows a method to make the above snippet work and fast in crystal? 

Thanks in advance.

Ryan Gonzalez

unread,
Aug 11, 2018, 10:39:12 AM8/11/18
to crysta...@googlegroups.com
The reason for the compile error is that Crystal's strings are immutable (they can't be modified). When you run:

x += "1"

That's the same thing as:

x = x + "1"

Basically, it's copying the string each iteration, which is why it's so slow. 

You can use String::Builder instead (https://crystal-lang.org/api/0.25.1/String/Builder.html):

builder = String::Builder.new
i = 0
while i < 200000
  builder << "1"
  i += 1
end

x = builder.to_s

FWIW instead of using a while loop, you can use Int.times, and you can use the Benchmark module to time the code (https://crystal-lang.org/api/0.25.1/Benchmark.html):

Benchmark.measure do
  builder = String::Builder.new
  200000.times do |i|
    builder << "1"
  end

  x = builder.to_s
end

Also remember to build in release mode (--release) to get the full performance!

--
You received this message because you are subscribed to the Google Groups "Crystal" group.
To unsubscribe from this group and stop receiving emails from it, send an email to crystal-lang...@googlegroups.com.
To post to this group, send email to crysta...@googlegroups.com.
Visit this group at https://groups.google.com/group/crystal-lang.
To view this discussion on the web visit https://groups.google.com/d/msgid/crystal-lang/d998ab61-2648-4633-a207-e5b308848e12%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--

Ryan (ライアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/

Jin Qian

unread,
Aug 11, 2018, 10:51:19 AM8/11/18
to Crystal
Thank you Ryan, you nailed it!   That's exactly what I need.
Reply all
Reply to author
Forward
0 new messages