2017-02-27 5 views
1

根本原因が実際にわからないという問題があります。transformerFactory.newTransformerがテスト中に遅くなる

私ははjavax.xml.transform.TransformerFactoryのインスタンスを作成し、直接、その後、私はxsltSourceを解析:

protected synchronized Transformer getTransformer(Source xsltSource) 
    throws TransformerConfigurationException { 

    TransformerFactory transformerFactory = TransformerFactory.newInstance(); 
    Transformer transformer = transformerFactory.newTransformer(xsltSource); 
    return transformer; 
} 

今私はテストスイートの一部であり、テストを持っています。このテストをスタンドアロンで実行すると、上記のコードは常に約1msかかります。

このテストをテストスイートの一部として実行すると時間がかかります。これは、gradleと同じように日食でも起こります。 継続時間は、前に実行されたテストの量に比例して増加します。

その特定のテストの前にどれだけ多くのテストを実行するかによって、その規模は10倍から1000倍のように遅くなります。

TransfomerFactoryのキャッシュされたインスタンスを使用すると、テストにかかる時間が半減します。しかし、症状は変わりません。
私はそれをプロファイリングしていますが、テストに時間がかかりますが、疑わしいものは表示されません。

何が原因である可能性がありますか?

編集私はcom.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImplを使用しています クラス。
JDKが提供するものはどれですか?

Edit2私は、ロードされたクラスの数と関係があると仮定しました(これは、テスト実行中に変更されるものです)。したがって、単一のテストのために任意にクラスをロードしましたが、タイミングは変更されませんでした。したがって、読み込まれたクラスの数はここでは誤りではないようです。

EDIT3私は私のクラスパスにサクソンパーサを追加し、特にその1を参照さ:

TransformerFactory transformerFactory = TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl", null);  
TransformerImpl transformer = (TransformerImpl) transformerFactory.newTransformer(xsltSource); 

行動はまだ同じで、テストスタンドアロンが速く実行されますが、テストスイートの一部としてそれがありますはるかに遅い。

Edit4私はこのコード行と同じ動作を持っている:

SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); 

それが遅くなり、より多くのテストは、特定のテストの前に実行されますが、それはスタンドアロンで実行された場合しません。

+1

実際のXMLトランスフォーマはどのようなものを使用していますか?組み込みのもの? xalan?サクソン? – MeBigFatGuy

答えて

0
掘り出して2日後に、xalanがクラスパス上のパスが多くなるほど時間がかかります。 sun.misc.CompoundEnumerationクラスを使用してそれをトラバースし、SaxParserFactoryの実装を探します.SaxParserFactoryの実装は、クラスパスをいっぱいにしてクラスローダーが検索する必要があるため、テストの実行時間が長くなりますより多くのクラス。

実際、最後の日に私たちの問題が本当に何かを考え出しました。我々
1.非常に頻繁に
2 TemplateFactoryの新しいインスタンスを作成したが
3.非常に頻繁のSAXParserFactoryの新しいインスタンスを作成し、当社のアルゴリズムで

は、我々はあまりにも非常に頻繁に再コンパイルテンプレートをキャッシュしませんでした、 それは同じだった。

ソリューションはTemplateFactoryと のSAXParserFactoryの1つのインスタンスを作成することでしたので、彼らはマルチスレッド実行と に呼び出しチェーンをそれらを渡すだけでなく、私たちの1つのテンプレートをキャッシュし、 はそれを再利用していけないことを確認してください。

最後に、JDK がTemplateFactoryの実装を探すために使用するチェーンがあり、ServiceLoaderを使用して SAXParserFactoryがあることがわかりました。 ServiceLoaderが実装のために がどのように見えるかなど、実際には長い時間がかかりました時間が経っていっぱいになっています(ServiceLoaderの ドキュメントでこれが実際に起こります)。 これらの インターフェイスのデフォルト実装のシステムプロパティを渡すと、それも修正されます。

すべての要求として私たちのパフォーマンスが

編集 :-) 90%以上向上したすべて、私はプロパティ自体を追加しませんではなく、正確に何が起こるか、何を説明したjavadocへのリンク、あなたがしなければならない。 https://docs.oracle.com/javase/7/docs/api/javax/xml/transform/TransformerFactory.html#newInstance()

これらは、あなたがそれを設定したもの、はjavax.xml.transform.TransformerFactoryjavax.xml.parsers.SAXParserFactory性質であるが、ことはどのJDKおよび/またはパーサに依存しますあなたが使っているライブラリ

+0

完全性のために、システムプロパティを設定する場所と方法を追加できますか? – Tschallacka

関連する問題