You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by "Sebastien Bocq (JIRA)" <ax...@ws.apache.org> on 2004/12/07 10:33:19 UTC
[jira] Created: (AXIS-1701) axis performance in multithreading env
axis performance in multithreading env
--------------------------------------
Key: AXIS-1701
URL: http://nagoya.apache.org/jira/browse/AXIS-1701
Project: Axis
Type: Bug
Components: Serialization/Deserialization
Versions: 1.2RC2
Environment: W2K, java full version "1.4.2_01-b06"
Reporter: Sebastien Bocq
Hi,
While doing performance tests on deserialization, I noticed that Axis
scales very poorly when increasing the number of threads.
Here are the figures:
5 threads, 1000 messages: 15 seconds
10 threads, 1000 messages: 56 seconds
15 threads, 1000 messages: 93 seconds
The root of the problem is in XMLUtils. Each time a node is created via
the static fuction newDocument(...), there are two functions,
getDocumentBuilder() and realeaseDocumentBuilder(), called which both
peform synchronisation over a pool of document builders
(documentBuilders ). Since XML documents contain many nodes and there
are at least two synchronization points in the code per node created, I
let you imagine the overhead suffered when more threads come into play.
I was able to achieve a significant performance boost by replacing the
pool of DocumentBuilders (documentBuilders) by a single document builder
stored in a ThreadLocal variable. This was already suggested a while ago
in this mailing list (see "Performance Issues with AXIS & Axis Response
time appears linear with load").
The results of my benchmark with the changes brought to the code are
shown below.
5 threads, 1000 messages: 13seconds
10 threads, 1000 messages: 25,5 seconds
15 threads, 1000 messages: 37 seconds
As you can see, deserialization time scales now linearly with the number
of threads which is a lot better. I placed a patch below. Could
you include sth equivalent in the next release of the Axis.
Thanks,
Sebastien
--- XMLUtilsOld.java Tue Nov 16 19:04:44 2004
+++ XMLUtilsNew.java Tue Dec 7 10:03:59 2004
@@ -80,8 +80,23 @@
private static final String saxParserFactoryProperty =
"javax.xml.parsers.SAXParserFactory";
- private static DocumentBuilderFactory dbf = getDOMFactory();
- private static Stack documentBuilders = new Stack();
+ // DocumentBuilderFactory is not thread-safe. Place DocumentBuilder
+ // in thread local variable to remove synchronization overhead.
+
+ // private static DocumentBuilderFactory dbf = getDOMFactory();
+ // private static Stack documentBuilders = new Stack();
+ private static class ThreadLocalDocumentBuilder extends ThreadLocal {
+ protected Object initialValue() {
+ try {
+ return getDOMFactory().newDocumentBuilder();
+ } catch (ParserConfigurationException e) {
+ log.error(Messages.getMessage("parserConfigurationException00"), e);
+ }
+ return null;
+ }
+ }
+ private static ThreadLocalDocumentBuilder documentBuilder = new ThreadLocalDocumentBuilder();
+
private static SAXParserFactory saxFactory;
private static Stack saxParsers = new Stack();
private static DefaultHandler doNothingContentHandler = new DefaultHandler();
@@ -206,36 +221,6 @@
}
return( dbf );
}
-
- /**
- * Gets a DocumentBuilder
- * @return DocumentBuilder
- * @throws ParserConfigurationException
- */
- public static DocumentBuilder getDocumentBuilder() throws ParserConfigurationException {
- synchronized (documentBuilders) {
- if (!documentBuilders.empty()) {
- return (DocumentBuilder) documentBuilders.pop();
- }
- }
- DocumentBuilder db = null;
- synchronized (dbf) {
- db = dbf.newDocumentBuilder();
- }
- return db;
- }
-
- /**
- * Releases a DocumentBuilder
- * @param db
- */
- public static void releaseDocumentBuilder(DocumentBuilder db) {
- synchronized (documentBuilders) {
- db.setErrorHandler(null); // setting implementation default
- db.setEntityResolver(null); // setting implementation default
- documentBuilders.push(db);
- }
- }
private static boolean tryReset= true;
@@ -302,16 +287,9 @@
*/
public static Document newDocument()
throws ParserConfigurationException {
- DocumentBuilder db = null;
- try {
- db = getDocumentBuilder();
- Document doc = db.newDocument();
- return doc;
- } finally {
- if (db != null) {
- releaseDocumentBuilder(db);
- }
- }
+ DocumentBuilder db = (DocumentBuilder) documentBuilder.get();
+ Document doc = db.newDocument();
+ return doc;
}
/**
@@ -324,18 +302,11 @@
public static Document newDocument(InputSource inp)
throws ParserConfigurationException, SAXException, IOException
{
- DocumentBuilder db = null;
- try {
- db = getDocumentBuilder();
- db.setEntityResolver(new DefaultEntityResolver());
- db.setErrorHandler(new ParserErrorHandler());
- Document doc = db.parse(inp);
- return doc;
- } finally {
- if (db != null) {
- releaseDocumentBuilder(db);
- }
- }
+ DocumentBuilder db = (DocumentBuilder) documentBuilder.get();
+ db.setEntityResolver(new DefaultEntityResolver());
+ db.setErrorHandler(new ParserErrorHandler());
+ Document doc = db.parse(inp);
+ return doc;
}
/**
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://nagoya.apache.org/jira/secure/Administrators.jspa
-
If you want more information on JIRA, or have a bug to report see:
http://www.atlassian.com/software/jira
[jira] Resolved: (AXIS-1701) axis performance in multithreading env
Posted by "Davanum Srinivas (JIRA)" <ax...@ws.apache.org>.
[ http://issues.apache.org/jira/browse/AXIS-1701?page=all ]
Davanum Srinivas resolved AXIS-1701:
------------------------------------
Resolution: Fixed
this has been fixed. please try latest CVS / Nightly.
thanks,
dims
> axis performance in multithreading env
> --------------------------------------
>
> Key: AXIS-1701
> URL: http://issues.apache.org/jira/browse/AXIS-1701
> Project: Axis
> Type: Bug
> Components: Serialization/Deserialization
> Versions: 1.2RC2
> Environment: W2K, java full version "1.4.2_01-b06"
> Reporter: Sebastien Bocq
>
> Hi,
> While doing performance tests on deserialization, I noticed that Axis
> scales very poorly when increasing the number of threads.
> Here are the figures:
> 5 threads, 1000 messages: 15 seconds
> 10 threads, 1000 messages: 56 seconds
> 15 threads, 1000 messages: 93 seconds
> The root of the problem is in XMLUtils. Each time a node is created via
> the static fuction newDocument(...), there are two functions,
> getDocumentBuilder() and realeaseDocumentBuilder(), called which both
> peform synchronisation over a pool of document builders
> (documentBuilders ). Since XML documents contain many nodes and there
> are at least two synchronization points in the code per node created, I
> let you imagine the overhead suffered when more threads come into play.
> I was able to achieve a significant performance boost by replacing the
> pool of DocumentBuilders (documentBuilders) by a single document builder
> stored in a ThreadLocal variable. This was already suggested a while ago
> in this mailing list (see "Performance Issues with AXIS & Axis Response
> time appears linear with load").
> The results of my benchmark with the changes brought to the code are
> shown below.
> 5 threads, 1000 messages: 13seconds
> 10 threads, 1000 messages: 25,5 seconds
> 15 threads, 1000 messages: 37 seconds
> As you can see, deserialization time scales now linearly with the number
> of threads which is a lot better. I placed a patch below. Could
> you include sth equivalent in the next release of the Axis.
> Thanks,
> Sebastien
> --- XMLUtilsOld.java Tue Nov 16 19:04:44 2004
> +++ XMLUtilsNew.java Tue Dec 7 10:03:59 2004
> @@ -80,8 +80,23 @@
> private static final String saxParserFactoryProperty =
> "javax.xml.parsers.SAXParserFactory";
>
> - private static DocumentBuilderFactory dbf = getDOMFactory();
> - private static Stack documentBuilders = new Stack();
> + // DocumentBuilderFactory is not thread-safe. Place DocumentBuilder
> + // in thread local variable to remove synchronization overhead.
> +
> + // private static DocumentBuilderFactory dbf = getDOMFactory();
> + // private static Stack documentBuilders = new Stack();
> + private static class ThreadLocalDocumentBuilder extends ThreadLocal {
> + protected Object initialValue() {
> + try {
> + return getDOMFactory().newDocumentBuilder();
> + } catch (ParserConfigurationException e) {
> + log.error(Messages.getMessage("parserConfigurationException00"), e);
> + }
> + return null;
> + }
> + }
> + private static ThreadLocalDocumentBuilder documentBuilder = new ThreadLocalDocumentBuilder();
> +
> private static SAXParserFactory saxFactory;
> private static Stack saxParsers = new Stack();
> private static DefaultHandler doNothingContentHandler = new DefaultHandler();
> @@ -206,36 +221,6 @@
> }
> return( dbf );
> }
> -
> - /**
> - * Gets a DocumentBuilder
> - * @return DocumentBuilder
> - * @throws ParserConfigurationException
> - */
> - public static DocumentBuilder getDocumentBuilder() throws ParserConfigurationException {
> - synchronized (documentBuilders) {
> - if (!documentBuilders.empty()) {
> - return (DocumentBuilder) documentBuilders.pop();
> - }
> - }
> - DocumentBuilder db = null;
> - synchronized (dbf) {
> - db = dbf.newDocumentBuilder();
> - }
> - return db;
> - }
> -
> - /**
> - * Releases a DocumentBuilder
> - * @param db
> - */
> - public static void releaseDocumentBuilder(DocumentBuilder db) {
> - synchronized (documentBuilders) {
> - db.setErrorHandler(null); // setting implementation default
> - db.setEntityResolver(null); // setting implementation default
> - documentBuilders.push(db);
> - }
> - }
>
> private static boolean tryReset= true;
>
> @@ -302,16 +287,9 @@
> */
> public static Document newDocument()
> throws ParserConfigurationException {
> - DocumentBuilder db = null;
> - try {
> - db = getDocumentBuilder();
> - Document doc = db.newDocument();
> - return doc;
> - } finally {
> - if (db != null) {
> - releaseDocumentBuilder(db);
> - }
> - }
> + DocumentBuilder db = (DocumentBuilder) documentBuilder.get();
> + Document doc = db.newDocument();
> + return doc;
> }
>
> /**
> @@ -324,18 +302,11 @@
> public static Document newDocument(InputSource inp)
> throws ParserConfigurationException, SAXException, IOException
> {
> - DocumentBuilder db = null;
> - try {
> - db = getDocumentBuilder();
> - db.setEntityResolver(new DefaultEntityResolver());
> - db.setErrorHandler(new ParserErrorHandler());
> - Document doc = db.parse(inp);
> - return doc;
> - } finally {
> - if (db != null) {
> - releaseDocumentBuilder(db);
> - }
> - }
> + DocumentBuilder db = (DocumentBuilder) documentBuilder.get();
> + db.setEntityResolver(new DefaultEntityResolver());
> + db.setErrorHandler(new ParserErrorHandler());
> + Document doc = db.parse(inp);
> + return doc;
> }
>
> /**
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira