gpt4 book ai didi

Swift 似乎比循环中的 Objective-C 慢

转载 作者:搜寻专家 更新时间:2023-10-30 22:31:42 25 4
gpt4 key购买 nike

我正在尝试将一些代码从 Objective-C 移植到 Swift,我用它来解析 HTML 文档。我基本上使用 NSXMLDocument 并为 HTMLDocument 和 HTMLNode 创建了自己的类,以带来一些额外的功能,如 getElementByID 等。

如果我现在比较移植的代码,Obj-C 中的解析需要 0.098 秒,Swift 中的代码需要 0.49 秒!我部分注释掉了代码,我可以看到,它与一些循环相关,在这些循环中,我将 NSXML 部分“翻译”到我自己的类中。例如:

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)
htmlNodes.append(node)
}
}
return htmlNodes
}

这是原始代码:(不要怀疑缺少 if ... > 0。如果 xmlNodes 为 nil,Obj-C 不会进入 for 循环。Swift 会带来运行时错误)

- (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;
}

这是 swift 的问题还是我监督了一些代码错误?

最佳答案

请记住,这两个环境是桥接的,这意味着如果您的 swift 代码调用 Objective-C 对象,您仍然要支付动态调度(即 objc_msgSend)惩罚。在这个循环中,你要循环的东西在 NSArray 中,所以所有循环调用(大概是 NSFastEnumeration)仍然必须每次都遍历桥。

“真正的”加速将来自纯 swift 的代码部分,并且不会碰到 Objective-C 桥。这与旧的“C++ 更快”论点实际上是相同的讨论。 C++ 更快,但前提是您不经常回调 Objective-C。

在理想情况下,这里最好的策略是使用原生的 swift XML 解析器(此时可能不存在),让你的模型和 Controller 对象都是纯 swift 的,并在它们交叉的地方使用垫片类到 Objective-C 的边界。如果我们谈论的是 C++ 而不是 swift,我会说,如果您将模型和 Controller 对象重写为原生 C++ 对象,然后使用纯 C++ XML 解析器,并且只在必须与之交互的地方使用 Objective-C用户界面,您会期望显着的性能提升。

当 swift 必须与 Objective-C 库交互时,它无法使这些库比以前更快,因此它们自然只能“一样快”或“更慢”。真正的胜利将来自纯粹的 swift 代码。很可能您也可以通过使用 swift 直接调用 C(或 C++)库来获得一些 yield ,但是通用的(即非 Apple 提供的)P/Invoke 故事(使用 .NET 词)在此刻。

关于Swift 似乎比循环中的 Objective-C 慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24030993/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com