作者:mobiledu2502915233 | 来源:互联网 | 2023-09-07 16:32
ImtryingtoportsomecodefromObjective-CtoSwift,withwhichIparseHTMLdocuments.Imusing
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.
我正在尝试将一些代码从Objective-C移植到Swift,我用它来解析HTML文档。我基本上使用NSXMLDocument并为HTMLDocument和HTMLNode创建了自己的类,以带来一些额外的功能,如getElementByID等。
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:
如果我现在比较移植的代码,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
}
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)
这是原始代码:(不要怀疑丢失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;
}
Is this a problem with swift or do I oversee some code error?
这是swift的问题还是我监督一些代码错误?
1 个解决方案
9
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.
请记住,这两个环境是桥接的,这意味着如果你的swift代码调用Objective-C对象,你仍然会支付动态调度(即objc_msgSend)惩罚。在这个循环中,你循环的东西都在NSArray中,所以所有循环调用(可能是NSFastEnumeration)仍然必须每次遍历桥。
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.
“真正的”加速将来自纯粹迅速并且没有达到Objective-C桥的代码部分。这与旧的“C ++更快”的论点完全相同。 C ++更快,但只有当你不经常回调到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.
在一个理想的世界中,这里最好的策略是使用原生的swift XML解析器(此时可能不存在),并让你的模型和控制器对象都是纯粹的快速类,它们跨越边界进入边界Objective-C的。如果我们讨论的是C ++而不是swift,我会说如果你将模型和控制器对象重写为本机C ++对象,然后使用纯C ++ XML解析器,并且只在必须与之交互时使用Objective-C用户界面,你会期望显着的性能提升。
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.
当swift必须与Objective-C库交互时,它不能使这些库比以前更快,所以很自然它们只能“快”或“慢”。真正的胜利将来自纯粹的快速代码。你可以通过使用swift直接调用C(或C ++)库来获得一些收益,但通用(即不是Apple提供的)P / Invoke故事(使用.NET字)并不十分清楚此时此刻。