From d810bbf68afc4287904b23a5a6c0d9c3f7333532 Mon Sep 17 00:00:00 2001 From: shado23 Date: Thu, 16 Nov 2017 19:08:06 +0100 Subject: [PATCH] Use a ThreadLocal to allow reusing parser instances Currently scala-xml creates a new SAXParser instance every time. This is not very good for performance, but explained by the fact that SAXParser is not thread safe. We can greatly increase performance by using a ThreadLocal, giving each thread their own instance. --- .../scala/scala/xml/factory/XMLLoader.scala | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/shared/src/main/scala/scala/xml/factory/XMLLoader.scala b/shared/src/main/scala/scala/xml/factory/XMLLoader.scala index 0604282ea..c759e599e 100644 --- a/shared/src/main/scala/scala/xml/factory/XMLLoader.scala +++ b/shared/src/main/scala/scala/xml/factory/XMLLoader.scala @@ -23,13 +23,18 @@ trait XMLLoader[T <: Node] { import scala.xml.Source._ def adapter: FactoryAdapter = new NoBindingFactoryAdapter() - /* Override this to use a different SAXParser. */ - def parser: SAXParser = { - val f = SAXParserFactory.newInstance() - f.setNamespaceAware(false) - f.newSAXParser() + private lazy val parserInstance = new ThreadLocal[SAXParser] { + override def initialValue = { + val parser = SAXParserFactory.newInstance() + + parser.setNamespaceAware(false) + parser.newSAXParser() + } } + /* Override this to use a different SAXParser. */ + def parser: SAXParser = parserInstance.get + /** * Loads XML from the given InputSource, using the supplied parser. * The methods available in scala.xml.XML use the XML parser in the JDK. @@ -58,4 +63,4 @@ trait XMLLoader[T <: Node] { /** Loads XML from the given String. */ def loadString(string: String): T = loadXML(fromString(string), parser) -} +} \ No newline at end of file