Wiremock version: 2.19.0
First of all, thank you for your work on wiremock, a very useful tool!
We are using wiremock for stubbing SOAP services in development environment.
We also tried to use Wiremock for performance tests, but there is some bottleneck:
Simply set system property -Djavax.xml.transform.TransformerFactory=<implementation to load> resolve this bottleneck
Simply set system property -Djavax.xml.xpath.XPathFactory:http://java.sun.com/jaxp/xpath/dom=<implementation to load> resolve this bottleneck
- XMLUnit.setXPathFactory and XMLUnit.setTransformerFactory
Predefine theses factories in XMLUnit also improve performance
Simple test case:
@Test
public void perfXmlTest() {
perfRunDatas("without optimisations");
// Optimisation 1
String xPathFactoryImpl = XPathFactory.newInstance().getClass().getName();
System.setProperty(XPathFactory.DEFAULT_PROPERTY_NAME + ":"
+ XPathFactory.DEFAULT_OBJECT_MODEL_URI, xPathFactoryImpl);
perfRunDatas("with XPathFactory system property");
// Optimisation 2
String transformerFactoryImpl = TransformerFactory.newInstance().getClass().getName();
System.setProperty(TransformerFactory.class.getName(), transformerFactoryImpl);
perfRunDatas("with XPathFactory/TransformerFactory system properties");
// Optimisation 3
XMLUnit.setTransformerFactory(transformerFactoryImpl);
perfRunDatas("with XPathFactory/TransformerFactory system properties and TransformerFactory predefined in XMLUnit");
// Optimisation 4
XMLUnit.setXPathFactory(xPathFactoryImpl);
perfRunDatas("with XPathFactory/TransformerFactory system properties and TransformerFactory/XPathFactory predefined in XMLUnit");
}
private void perfRunDatas(String string) {
long ts = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
WireMock.matchingXPath("//perf-test").match("<perf-test>perf-data</perf-test>");
}
System.out.println(string + ":\n" + (System.currentTimeMillis() - ts) + "ms");
}
generate this:
without optimisations:
23745ms
with XPathFactory system property:
12690ms
with XPathFactory/TransformerFactory system properties:
2032ms
with XPathFactory/TransformerFactory system properties and TransformerFactory predefined in XMLUnit:
1981ms
with XPathFactory/TransformerFactory system properties and TransformerFactory/XPathFactory predefined in XMLUnit:
1767ms
So, simply adding to system properties:
-Djavax.xml.transform.TransformerFactory=<implementation>
-Djavax.xml.xpath.XPathFactory:http://java.sun.com/jaxp/xpath/dom=<implementation>
and predefining factories in XMLUnit library improved performance by 10 !
I think this should be described in documentation, or implemented in Wiremock.
An implementation could be calling this method optimizeFactoriesLoading() during WireMock initialisation :
public void optimizeFactoriesLoading() {
String transformerFactoryImpl = TransformerFactory.newInstance().getClass().getName();
String xPathFactoryImpl = XPathFactory.newInstance().getClass().getName();
setProperty(TransformerFactory.class.getName(), transformerFactoryImpl);
setProperty(XPathFactory.DEFAULT_PROPERTY_NAME + ":" + XPathFactory.DEFAULT_OBJECT_MODEL_URI,
xPathFactoryImpl);
XMLUnit.setTransformerFactory(transformerFactoryImpl);
XMLUnit.setXPathFactory(xPathFactoryImpl);
}
private String setProperty(final String name, final String value) {
return AccessController.doPrivileged(new PrivilegedAction<String>() {
@Override
public String run() {
return System.setProperty(name, value);
}
});
}
Wiremock version: 2.19.0
First of all, thank you for your work on wiremock, a very useful tool!
We are using wiremock for stubbing SOAP services in development environment.
We also tried to use Wiremock for performance tests, but there is some bottleneck:
This factory is instanciate everywhere in XMLUnit library and WireMock, but algorithm to determine the implementation class to load is heavy:
https://docs.oracle.com/javase/7/docs/api/javax/xml/transform/TransformerFactory.html#newInstance()
Simply set system property
-Djavax.xml.transform.TransformerFactory=<implementation to load>resolve this bottleneckThis factory is instanciate everywhere in XMLUnit library and WireMock, but algorithm to determine the implementation class to load is heavy:
https://docs.oracle.com/javase/7/docs/api/javax/xml/xpath/XPathFactory.html#newInstance()
https://github.com/openjdk-mirror/jdk7u-jaxp/blob/master/src/javax/xml/xpath/XPathFactoryFinder.java#L156
Simply set system property
-Djavax.xml.xpath.XPathFactory:http://java.sun.com/jaxp/xpath/dom=<implementation to load>resolve this bottleneckPredefine theses factories in XMLUnit also improve performance
Simple test case:
generate this:
without optimisations:
23745ms
with XPathFactory system property:
12690ms
with XPathFactory/TransformerFactory system properties:
2032ms
with XPathFactory/TransformerFactory system properties and TransformerFactory predefined in XMLUnit:
1981ms
with XPathFactory/TransformerFactory system properties and TransformerFactory/XPathFactory predefined in XMLUnit:
1767ms
So, simply adding to system properties:
-Djavax.xml.transform.TransformerFactory=<implementation>-Djavax.xml.xpath.XPathFactory:http://java.sun.com/jaxp/xpath/dom=<implementation>and predefining factories in XMLUnit library improved performance by 10 !
I think this should be described in documentation, or implemented in Wiremock.
An implementation could be calling this method
optimizeFactoriesLoading()during WireMock initialisation :