Consider the following array -of strings-:
let arrayStrings = ["H", "e", "l", "l", "o"]
For combining its elements (to get "Hello" as single String), we could:
reduce it:
let reducedString = arrayStrings.reduce("", { $0 + $1 }) // "Hello"
Or join it:
let joinedString = arrayStrings.joined() // "Hello"
Both would return "Hello" String as output.
However, what is the logic to keep in mind to determine what is the better choice for such a process? What is the difference when comparing based on the performance?
There are two reasons why joined
is a better choice than reduce
:
Readability
If you want to join multiple strings into one string, why would you use reduce
, with manual concatenation? If there is a specific function for the task you want to do, use it. When reading the code, it's easier to understand joined
than reduce
.
Performance
joined
for String
can be implemented better than reduce
. It does not have to be but it can. reduce
operates on one element at a time, without knowledge about the other elements, with many temporary variables passed around. joined
has the knowledge of the entire sequence and it knows that the operation is always the same, therefore it can optimize. It can even use the internal structure of String
. See String.joined implementation.
In summary, always use the more specific implementation. Note that the performance reason above is the less important one.
Update The previous results were obtained by running an iOS app on the simulator. Running the app on a real device, or running the code from a MacOS command line app gives similar results to ones @Sulthan mentioned.
Interestingly enough, reduce
gave better results on my machine:
func benchmark(_ label: String, times: Int = 100000, _ f: () -> Void) {
let start = CACurrentMediaTime()
(0..<times).forEach { _ in f() }
let end = CACurrentMediaTime()
print("\(label) took \(end-start)")
}
let arrayStrings = ["H", "e", "l", "l", "o"]
benchmark("reduce", { _ = arrayStrings.reduce("", +) } )
benchmark("join", { _ = arrayStrings.joined() })
The results were around the following numbers when run from the main
method of a typical iOS app, build in Debug mode:
reduce took 0.358474982960615
join took 0.582276367989834
Same app, built in Release mode, gave the same order of results:
reduce took 0.126910287013743
join took 0.0291724550188519
I ran the benchmarks multiple times, and reduce
performed better in all cases. The difference is not that big though, so unless your string operations are critical in regards to performance, I'd recommend using joined
, that method carries more semantical value, it better transmits the intent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With