Ruby - Array.join versus String Concatenation (Efficiency)
Try it yourself with the Benchmark class.
require "benchmark"
n = 1000000
Benchmark.bmbm do |x|
x.report("concatenation") do
foo = ""
n.times do
foo << "foobar"
end
end
x.report("using lists") do
foo = []
n.times do
foo << "foobar"
end
string = foo.join
end
end
This produces the following output:
Rehearsal -------------------------------------------------
concatenation 0.300000 0.010000 0.310000 ( 0.317457)
using lists 0.380000 0.050000 0.430000 ( 0.442691)
---------------------------------------- total: 0.740000sec
user system total real
concatenation 0.260000 0.010000 0.270000 ( 0.309520)
using lists 0.310000 0.020000 0.330000 ( 0.363102)
So it looks like concatenation is a little faster in this case. Benchmark on your system for your use-case.
Ruby Array concat versus + speed?
According to the Ruby docs, the difference is:
Array#+ :
Concatenation — Returns a new array built by concatenating the two arrays together to produce a third array.
Array#concat :
Array#concat : Appends the elements of other_ary to self.
So the +
operator will create a new array each time it is called (which is expensive), while concat
only appends the new element.
Ruby differences between += and to concatenate a string
The shovel operator <<
performs much better than +=
when dealing with long strings because the shovel operator is allowed to modify the original string, whereas +=
has to copy all the text from the first string into a new string every time it runs.
There is no +=
operator defined on the String class, because +=
is a combined operator. In short x += "asdf"
is exactly equivalent to x = x + "asdf"
, so you should reference the +
operator on the string class, not look for a +=
operator.
How to efficiently concatenate multiple arrays in Ruby?
If you've already determined that multiple concatenation is the fastest method, you can write it nicer using reduce:
[foo, bar, baz].reduce([], :concat)
String concatenation in Ruby
You can do that in several ways:
- As you shown with
<<
but that is not the usual way With string interpolation
source = "#{ROOT_DIR}/#{project}/App.config"
with
+
source = "#{ROOT_DIR}/" + project + "/App.config"
The second method seems to be more efficient in term of memory/speed from what I've seen (not measured though). All three methods will throw an uninitialized constant error when ROOT_DIR is nil.
When dealing with pathnames, you may want to use File.join
to avoid messing up with pathname separator.
In the end, it is a matter of taste.
String concatenation vs. interpolation in Ruby
Whenever TIMTOWTDI (there is more than one way to do it), you should look for the pros and cons. Using "string interpolation" (the second) instead of "string concatenation" (the first):
Pros:
- Is less typing
- Automatically calls
to_s
for you - More idiomatic within the Ruby community
- Faster to accomplish during runtime
Cons:
- Automatically calls
to_s
for you (maybe you thought you had a string, and theto_s
representation is not what you wanted, and hides the fact that it wasn't a string) - Requires you to use
"
to delimit your string instead of'
(perhaps you have a habit of using'
, or you previously typed a string using that and only later needed to use string interpolation)
String Concatenation in Efficient Way
c = a + "," + b
# or
c = a << "," << b # warning: will modify 'a'
Just use simple string concatenation (the +
/<<
operator). Note that if you use <<
, then a
will be modified, so the first method is probably a better idea unless you don't care about a
any more.
For many strings, first put them in an array:
myArray = ['some string', 'another string', 'string']
Then use the join function:
myArray.join(',') # some string,another string,string
# or
myArray * ',' # same as above, * is an alias for join
Ruby concatenate strings and add spaces
[name, quest, favorite_color, speed].reject(&:empty?).join(' ')
Related Topics
How to Detect Browser Type and Its Version
What Is Purpose of Around_Create Callback in Rails Model
What Does "No Binary Rubies Available" Mean
Perform One Validation Only If All Other Validations Pass
How to Escape a Single Quote in Ruby
How to Pass <Arguments> to Irb If I Don't Specify <Programfile>
(Ruby) How to Check Whether a Range Contains a Subset of Another Range
Collecting Hashes into Openstruct Creates "Table" Entry
Error: While Executing Gem ... (Typeerror) Incompatible Marshal File Format (Can't Be Read)
Reversing the Order of an Array in Ruby
Rspec: How to Write a Test That Expects Certain Output But Doesn't Care About the Method
Rails Scaffolding Pluralisation Is Incorrect for "Cafe"
How to Globally Ignore Invalid Byte Sequences in Utf-8 Strings
What Graphing Packages/Apis Exist for Ruby
Dynamically Generate Scopes in Rails Models
Ruby Gem Listed, But Won't Load (Gem in User Dir, Not Ruby Dir)