好吧,我添加这个以供其他想知道他们是否需要放弃 JAXB 的人参考。
添加
-Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
完成了这项工作。现在的性能具有相同的数量级。看来我们有一个简单的类路径问题。在 large 类路径上,(未缓存的)DocumentBuilderFactory 所需的服务提供者查找是导致性能不佳的关键因素。给虚拟机一个已知的实现以避免搜索....
我在“随机”分析之后尝试过这个(随时按暂停 :-) 总是以这样的搜索顺序结束:
Thread [main] (Suspended)
owns: VirtualKeyStoreHolder (id=417)
owns: CertificateStoreEnvironment (id=418)
owns: ManagedCertificateProvider (id=419)
owns: CertificateStoreEnvironment$1 (id=420)
WinNTFileSystem.getBooleanAttributes(File) line: not available [native method]
File.exists() line: 733
URLClassPath$FileLoader.getResource(String, boolean) line: 999
URLClassPath$FileLoader.findResource(String, boolean) line: 966
URLClassPath.findResource(String, boolean) line: 146
URLClassLoader$2.run() line: 385
AccessController.doPrivileged(PrivilegedAction<T>, AccessControlContext) line: not available [native method]
Launcher$AppClassLoader(URLClassLoader).findResource(String) line: 382
Launcher$AppClassLoader(ClassLoader).getResource(String) line: 1003
Launcher$AppClassLoader(ClassLoader).getResourceAsStream(String) line: 1193
SecuritySupport$4.run() line: 96
AccessController.doPrivileged(PrivilegedAction<T>) line: not available [native method]
SecuritySupport.getResourceAsStream(ClassLoader, String) line: 89
FactoryFinder.findJarServiceProvider(String) line: 250
FactoryFinder.find(String, String) line: 223
DocumentBuilderFactory.newInstance() line: 123
TransformerIdentityImpl.createResultContentHandler(Result) line: 215
TransformerIdentityImpl.setDocumentLocator(Locator) line: 881
DomLoader$State.<init>(DomLoader, UnmarshallingContext) line: 78
DomLoader<ResultT>.startElement(UnmarshallingContext$State, TagName) line: 113
XsiTypeLoader.startElement(UnmarshallingContext$State, TagName) line: 76
UnmarshallingContext._startElement(TagName) line: 481
UnmarshallingContext.startElement(TagName) line: 459
SAXConnector.startElement(String, String, String, Attributes) line: 148
SAXParserImpl$JAXPSAXParser(AbstractSAXParser).startElement(QName, XMLAttributes, Augmentations) line: 501
XMLNSDocumentScannerImpl.scanStartElement() line: 400
XMLNSDocumentScannerImpl$NSContentDriver(XMLDocumentFragmentScannerImpl$FragmentContentDriver).next() line: 2755
XMLNSDocumentScannerImpl(XMLDocumentScannerImpl).next() line: 648
XMLNSDocumentScannerImpl.next() line: 140
XMLNSDocumentScannerImpl(XMLDocumentFragmentScannerImpl).scanDocument(boolean) line: 511
XIncludeAwareParserConfiguration(XML11Configuration).parse(boolean) line: 808
XIncludeAwareParserConfiguration(XML11Configuration).parse(XMLInputSource) line: 737
SAXParserImpl$JAXPSAXParser(XMLParser).parse(XMLInputSource) line: 119
SAXParserImpl$JAXPSAXParser(AbstractSAXParser).parse(InputSource) line: 1205
SAXParserImpl$JAXPSAXParser.parse(InputSource) line: 522
UnmarshallerImpl.unmarshal0(XMLReader, InputSource, JaxBeanInfo) line: 211
UnmarshallerImpl.unmarshal(XMLReader, InputSource) line: 184
UnmarshallerImpl(AbstractUnmarshallerImpl).unmarshal(InputSource) line: 137
UnmarshallerImpl(AbstractUnmarshallerImpl).unmarshal(InputStream) line: 184
VirtualKeyStoreTools.createVirtualKeyStore(InputStream) line: 54
... more to come
由于有悬而未决的赏金,我将把它提供给@Osw(当可以应用赏金时),因为答案“是的,你可以 JAXB”是正确的。我认为微小的性能差异并不能证明使用计划 SAX 解决方案或不再使用蒸煮器是合理的。此外,缓存 JAXBContext 似乎是明智的,我不知道缓存 unmarshaller 上下文 - 也许有人添加了有关此的信息。
感谢您的支持。
编辑
根据@Osw 的要求,这里有一些(令人失望的)数据,以反映由此产生的整体性能。
我直接围绕解析为新旧应用程序做了一些肮脏的检测。虽然对于加载一堆文件的交互式应用程序而言,这些数字是“可接受的”,但我必须承认消化器的速度仍然超过 2 倍。
- 基于摘要器,约 1 MB 文件,包含 4000 个通用条目 = 400 毫秒
- 基于 JAXB,见上文,900 毫秒
JAXB 实现已经包含一个用于解组器的缓存,因此完成了“开箱即用”的优化。这给我留下了一个迫切需要更多分析的功能应用程序。完成后我会回来,并且会弹出一些普遍感兴趣的有趣技巧。