net.sf.saxon.s9api.XsltTransformer设计为一次性使用吗?

时间:2015-02-03 15:27:47

标签: saxon

我不相信我充分理解XsltTransformer类足以解释为什么方法f1优于f2。事实上,f1在大约40秒内完成,消耗750mbB和1GB内存。我期待f2是一个更好的解决方案,但它永远不会完成相同冗长的输入文件列表。当我杀了它时,它只处理了大约1000个输入文件,同时消耗了超过4GB的内存。

import java.io.*;
import javax.xml.transform.stream.StreamSource;
import net.sf.saxon.s9api.*;
public class foreachfile {
    private static long f1 (Processor p, XsltExecutable e, Serializer ser, String args[]) {
        long maxTotalMemory = 0;
        Runtime rt = Runtime.getRuntime();
        for (int i=1; i<args.length; i++) {
            String xmlfile = args[i];
            try {
                XsltTransformer t = e.load();
                t.setDestination(ser);
                t.setInitialContextNode(p.newDocumentBuilder().build(new StreamSource(new File(xmlfile))));
                t.transform();
                long tm = rt.totalMemory();
                if (tm > maxTotalMemory)
                    maxTotalMemory = tm;
            } catch (Throwable ex) {
                System.err.println(ex);
            }
        }
        return maxTotalMemory;
    }
    private static long f2 (Processor p, XsltExecutable e, Serializer ser, String args[]) {
        long maxTotalMemory = 0;
        Runtime rt = Runtime.getRuntime();
        XsltTransformer t = e.load();
        t.setDestination(ser);
        for (int i=1; i<args.length; i++) {
            String xmlfile = args[i];
            try {
                t.setInitialContextNode(p.newDocumentBuilder().build(new StreamSource(new File(xmlfile))));
                t.transform();
                long tm = rt.totalMemory();
                if (tm > maxTotalMemory)
                    maxTotalMemory = tm;
            } catch (Throwable ex) {
                System.err.println(ex);
            }
        }
        return maxTotalMemory;
    }
    public static void main (String args[]) throws SaxonApiException, Exception {
        String usecase = System.getProperty("xslt.usecase");
        int uc = Integer.parseInt(usecase);
        String xslfile = args[0];
        Processor p = new Processor(true);
        XsltCompiler c = p.newXsltCompiler();
        XsltExecutable e = c.compile(new StreamSource(new File(xslfile)));
        Serializer ser = new Serializer();
        ser.setOutputStream(System.out);
        long maxTotalMemory = uc == 1  ?  f1(p, e, ser, args)  :  f2(p, e, ser, args);
        System.err.println(String.format("Max total memory was %d", maxTotalMemory));
    }
}

1 个答案:

答案 0 :(得分:1)

我通常建议为每次转换使用新的XsltTransformer。但是,该类是可串行重用的(您可以一个接一个地执行多个转换,但不能同时执行)。 XsltTransformer将某些资源保留在内存中,以防再次需要它们:特别是,使用doc()或document()函数读取的所有文档。例如,如果要将一组输入文档转换为五种不同的输出格式(作为发布工作流程的一部分),这可能很有用。但是,如果这种资源的重用并没有给你带来任何好处,那么它只会增加内存使用成本,你可以通过每次创建一个新的变换器来避免这种成本。如果使用JAXP接口,则同样适用。