component(separatedBy:) versus .split(separator: )
Asked Answered
E

3

23

In Swift 4, new method .split(separator:) is introduced by apple in String struct. So to split a string with whitespace which is faster for e.g..

let str = "My name is Sudhir"

str.components(separatedBy: " ")

//or 

str.split(separator: " ")
Eider answered 21/9, 2017 at 13:1 Comment(5)
I don't think this has any performance differences.Tzar
Why don't you test it and measure the performance? – Btw, the method is not new in Swift 4, see e.g. https://mcmap.net/q/276774/-swift-version-of-componentsseparatedbystring.Typical
@MartinR please see developer.apple.com/documentation/swift/… mention by apple that its added by them in latest versionEider
Looking into code, .components delegates to NSString while split is implemented through Collection interface. According to FIXME:, components will be in future delegated to split, see github.com/apple/swift/blob/…Aw
@Sudhirkumar: We are both right in some sense :) – In Swift 3 it was str.characters.split(...) because a String itself was not a collection.Typical
E
13

I have made sample test with following Code.

  var str = """
                One of those refinements is to the String API, which has been made a lot easier to use (while also gaining power) in Swift 4. In past versions of Swift, the String API was often brought up as an example of how Swift sometimes goes too far in favoring correctness over ease of use, with its cumbersome way of handling characters and substrings. This week, let’s take a look at how it is to work with strings in Swift 4, and how we can take advantage of the new, improved API in various situations. Sometimes we have longer, static strings in our apps or scripts that span multiple lines. Before Swift 4, we had to do something like inline \n across the string, add an appendOnNewLine() method through an extension on String or - in the case of scripting - make multiple print() calls to add newlines to a long output. For example, here is how TestDrive’s printHelp() function (which is used to print usage instructions for the script) looks like in Swift 3  One of those refinements is to the String API, which has been made a lot easier to use (while also gaining power) in Swift 4. In past versions of Swift, the String API was often brought up as an example of how Swift sometimes goes too far in favoring correctness over ease of use, with its cumbersome way of handling characters and substrings. This week, let’s take a look at how it is to work with strings in Swift 4, and how we can take advantage of the new, improved API in various situations. Sometimes we have longer, static strings in our apps or scripts that span multiple lines. Before Swift 4, we had to do something like inline \n across the string, add an appendOnNewLine() method through an extension on String or - in the case of scripting - make multiple print() calls to add newlines to a long output. For example, here is how TestDrive’s printHelp() function (which is used to print usage instructions for the script) looks like in Swift 3
          """

    var newString = String()

    for _ in 1..<9999 {
        newString.append(str)
    }

    var methodStart = Date()

 _  = newString.components(separatedBy: " ")
    print("Execution time Separated By: \(Date().timeIntervalSince(methodStart))")

    methodStart = Date()
    _ = newString.split(separator: " ")
    print("Execution time Split By: \(Date().timeIntervalSince(methodStart))")

I run above code on iPhone6 , Here are the results

Execution time Separated By: 8.27463299036026 Execution time Split By: 4.06880903244019

Conclusion : split(separator:) is faster than components(separatedBy:).

Eider answered 21/9, 2017 at 13:49 Comment(6)
Which optimization level have you used?Aw
Sorry didn't understand. I simply test both methods on same set of input and check execution time taken by each method.Eider
The comparison does not make sense if you don't have full optimization enabled.Aw
Then please help me , How do I test it.Eider
Use of components is returning a [String], where split is returning [Substring]. Each String is a String allocation, Substring is only using references, does not allocate new String and is faster and cheaper.Yarkand
@Sudhirkumar he's referring to Swift optimization level in Xcode -> Target -> Build settings. If you run your app in debug mode, by default it's Onone; you can manually change it to product level "fast" optimization level. Check this out if you still can't find it: github.com/hyperoslo/BarcodeScanner/issues/106Gracia
S
23

Performance aside, there is an important difference between split(separator:) and components(separatedBy:) in how they treat empty subsequences.

They will produce different results if your input contains a trailing whitespace:

    let str = "My name is Sudhir " // trailing space

    str.split(separator: " ")
    // ["My", "name", "is", "Sudhir"]

    str.components(separatedBy: " ")
    // ["My", "name", "is", "Sudhir", ""] ← Additional empty string

To have both produce the same result, use the omittingEmptySubsequences:false argument (which defaults to true):

    // To get the same behavior:
    str.split(separator: " ", omittingEmptySubsequences: false)
    // ["My", "name", "is", "Sudhir", ""]

Details here:

https://developer.apple.com/documentation/swift/string/2894564-split

Stanleigh answered 9/4, 2020 at 10:57 Comment(1)
Yes, this the the true answer.Overhasty
E
13

I have made sample test with following Code.

  var str = """
                One of those refinements is to the String API, which has been made a lot easier to use (while also gaining power) in Swift 4. In past versions of Swift, the String API was often brought up as an example of how Swift sometimes goes too far in favoring correctness over ease of use, with its cumbersome way of handling characters and substrings. This week, let’s take a look at how it is to work with strings in Swift 4, and how we can take advantage of the new, improved API in various situations. Sometimes we have longer, static strings in our apps or scripts that span multiple lines. Before Swift 4, we had to do something like inline \n across the string, add an appendOnNewLine() method through an extension on String or - in the case of scripting - make multiple print() calls to add newlines to a long output. For example, here is how TestDrive’s printHelp() function (which is used to print usage instructions for the script) looks like in Swift 3  One of those refinements is to the String API, which has been made a lot easier to use (while also gaining power) in Swift 4. In past versions of Swift, the String API was often brought up as an example of how Swift sometimes goes too far in favoring correctness over ease of use, with its cumbersome way of handling characters and substrings. This week, let’s take a look at how it is to work with strings in Swift 4, and how we can take advantage of the new, improved API in various situations. Sometimes we have longer, static strings in our apps or scripts that span multiple lines. Before Swift 4, we had to do something like inline \n across the string, add an appendOnNewLine() method through an extension on String or - in the case of scripting - make multiple print() calls to add newlines to a long output. For example, here is how TestDrive’s printHelp() function (which is used to print usage instructions for the script) looks like in Swift 3
          """

    var newString = String()

    for _ in 1..<9999 {
        newString.append(str)
    }

    var methodStart = Date()

 _  = newString.components(separatedBy: " ")
    print("Execution time Separated By: \(Date().timeIntervalSince(methodStart))")

    methodStart = Date()
    _ = newString.split(separator: " ")
    print("Execution time Split By: \(Date().timeIntervalSince(methodStart))")

I run above code on iPhone6 , Here are the results

Execution time Separated By: 8.27463299036026 Execution time Split By: 4.06880903244019

Conclusion : split(separator:) is faster than components(separatedBy:).

Eider answered 21/9, 2017 at 13:49 Comment(6)
Which optimization level have you used?Aw
Sorry didn't understand. I simply test both methods on same set of input and check execution time taken by each method.Eider
The comparison does not make sense if you don't have full optimization enabled.Aw
Then please help me , How do I test it.Eider
Use of components is returning a [String], where split is returning [Substring]. Each String is a String allocation, Substring is only using references, does not allocate new String and is faster and cheaper.Yarkand
@Sudhirkumar he's referring to Swift optimization level in Xcode -> Target -> Build settings. If you run your app in debug mode, by default it's Onone; you can manually change it to product level "fast" optimization level. Check this out if you still can't find it: github.com/hyperoslo/BarcodeScanner/issues/106Gracia
Y
1

Maybe a little late to answer:

When you play with them, they behave a little bit different:

str.components(separatedBy: "\n\n")

This call can give you some interesting results

str.split(separator: "\n\n")

This leads to an compile error as you must provide a single character.

Yonyona answered 2/12, 2022 at 15:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.