Swift seems to be slower as Objective-C in loops

I’m trying to port some code from Objective-C to Swift, with which I parse HTML documents. I’m using basically the NSXMLDocument and created own classes for HTMLDocument and HTMLNode to bring some extra functionality like getElementByID and so on.

If I now compare the ported code, the parsing in Obj-C needs 0.098 seconds, the code in Swift needs 0.49 seconds! I partly commented out the code and I could see, that it correlates with some loops, in which I “translate” the NSXML part to my own class. For example:

  • Sorting an array of dictionaries in Swift 2
  • Change Status Bar Background Color in Swift 3
  • iOS app doesn't ask for location permission
  • How can I convert string date to NSDate?
  • How do I execute code once and only once in Swift?
  • Dynamic tableViewCell height
  • func getElementsByTagName(tagName: String) -> HTMLNode[] {
        let xPath = ".//\(tagName)"
        let xmlNodes = xmlElement.nodesForXPath(xPath, error: nil)
        var htmlNodes = HTMLNode[]()
        if xmlNodes.count > 0 {
            for element in xmlNodes as NSXMLNode[] {
                var node = HTMLNode(xmlElement: element as NSXMLElement)
        return htmlNodes

    This is the original code:
    (don’t wonder about the missing if … > 0. Obj-C don’t enter the for loop, if xmlNodes is nil. Swift brings a runtime error)

    - (NSArray*)getElementsByTagName:(NSString*)tagName {
        NSString *xPath = [NSString stringWithFormat:@".//%@", tagName];
        NSArray *xmlNodes = [self.xmlElement nodesForXPath:xPath error:nil];
        NSMutableArray *htmlNodes = [[NSMutableArray alloc] init];
        for (NSXMLElement *el in xmlNodes) {
            HTMLNode *node = [HTMLNode initWithXMLElement:el];
            [htmlNodes addObject:node];
        return htmlNodes;

    Is this a problem with swift or do I oversee some code error?

    Solutions Collect From Internet About “Swift seems to be slower as Objective-C in loops”

    Remember, these two environments are bridged, which means that if your swift code calls into Objective-C objects, you’re still going to pay the dynamic dispatch (i.e. objc_msgSend) penalty. In this loop, the things you’re looping over are in an NSArray so all the looping calls (presumably NSFastEnumeration) still have to traverse the bridge every time.

    The “real” speedup is going to come from sections of code that are pure swift and don’t hit the Objective-C bridge. This is really the same discussion as the old “C++ is faster” argument. C++ is faster, but only if you’re not constantly calling back into Objective-C.

    In an ideal world, the best strategy here would be to use a native swift XML parser (which probably doesn’t exist at this point) and have your model and controller objects all be pure swift with shim classes for where they cross the border into Objective-C. If we were talking about C++ instead of swift, I would say that if you rewrote your model and controller objects as native C++ objects and then used a pure C++ XML parser, and only used Objective-C at the point where you had to interact with the UI, you would expect significant performance gains.

    When swift has to interact with Objective-C libraries, it can’t make those libraries any faster than they were before, so naturally they can only be “as fast” or “slower.” The real wins will come from pure swift code. It’s likely that you could also get some gains by using swift to call directly into C (or C++) libraries but the generic (i.e. not-Apple-provided) P/Invoke story (to use a .NET word) is not very clear at the moment.