代码之家  ›  专栏  ›  技术社区  ›  Ruwanka De Silva

在jmh@setup中初始化fileinputstream并在@benchmark中使用

  •  2
  • Ruwanka De Silva  · 技术社区  · 7 年前

    InputStream 入选 @Setup ,尝试在 @Benchmark 它关闭了。改变 @State 不起作用。我做得对吗?是否有方法避免流初始化开销并执行适当的基准测试?

    这个不适用于 XMLStreamReader 另外,我正在做一个序列化反序列化基准测试,我想避免文件读取/流初始化成本进入基准分数。

    样本基准

    @State( Scope.Thread )
    public class DeserializationBenchMark
    {
        @Param( { "1.xml", "10.xml", "100.xml" } )
        String file;
    
        private InputStream xmlFileInputStream;
    
        @Setup
        public void setup() throws JAXBException, IOException, SAXException, XMLStreamException
        {
            File xmlFile = new File( "src/main/resources/" + file );
            xmlFileInputStream = Files.newInputStream( xmlFile.toPath() );
        }
    
        @Benchmark
        public void jacksonDeserializeStreamTest( Blackhole bh ) throws IOException
        {
            bh.consume( objectMapper.readValue( xmlFileInputStream, Cat.class ) );
        }
    
    }
    

    跑步者

    public class BenchMarkRunner
    {
        public static void main( String[] args ) throws RunnerException
        {
            Options opt = new OptionsBuilder()
                                  .include( DeserializationBenchMark.class.getSimpleName() )
                                  .forks( 1 )
                                  .resultFormat( ResultFormatType.JSON )
                                  .result( "deserialize-benchmark-report-" + LocalDateTime.now().format( DateTimeFormatter.ofPattern( "ddMMyyyy'T'hhmmss" ) ) + ".json" )
                                  .mode( Mode.AverageTime )
                                  .warmupIterations( 3 )
                                  .measurementIterations( 5 )
                                  .timeUnit( TimeUnit.MICROSECONDS )
                                  .build();
    
            new Runner( opt ).run();
        }
    }
    

    这给了

    com.fasterxml.jackson.core.JsonParseException: N/A
        at com.fasterxml.jackson.dataformat.xml.util.StaxUtil.throwAsParseException(StaxUtil.java:37)
        at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:534)
        at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:29)
        at com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:820)
        at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3058)
        at com.example.DeserializationBenchMark.jacksonDeserializeStreamTest(DeserializationBenchMark.java:118)
        at com.example.generated.DeserializationBenchMark_jacksonDeserializeStreamTest_jmhTest.jacksonDeserializeStreamTest_avgt_jmhStub(DeserializationBenchMark_jacksonDeserializeStreamTest_jmhTest.java:186)
        at com.example.generated.DeserializationBenchMark_jacksonDeserializeStreamTest_jmhTest.jacksonDeserializeStreamTest_AverageTime(DeserializationBenchMark_jacksonDeserializeStreamTest_jmhTest.java:150)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:453)
        at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:437)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
    Caused by: java.nio.channels.ClosedChannelException
        at sun.nio.ch.FileChannelImpl.ensureOpen(FileChannelImpl.java:110)
        at sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:147)
        at sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:65)
        at sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:109)
        at sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:103)
        at com.ctc.wstx.io.StreamBootstrapper.ensureLoaded(StreamBootstrapper.java:482)
        at com.ctc.wstx.io.StreamBootstrapper.resolveStreamEncoding(StreamBootstrapper.java:306)
        at com.ctc.wstx.io.StreamBootstrapper.bootstrapInput(StreamBootstrapper.java:167)
        at com.ctc.wstx.stax.WstxInputFactory.doCreateSR(WstxInputFactory.java:573)
        at com.ctc.wstx.stax.WstxInputFactory.createSR(WstxInputFactory.java:633)
        at com.ctc.wstx.stax.WstxInputFactory.createSR(WstxInputFactory.java:647)
        at com.ctc.wstx.stax.WstxInputFactory.createXMLStreamReader(WstxInputFactory.java:334)
        at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:532)
        ... 18 more
    

    任何建议都很好!谢谢您。

    PS:

    正如@dit所提到的,它应该是流关闭的,任何知道它为什么在第一次迭代时发生,

    # Run progress: 0.00% complete, ETA 00:07:30
    # Fork: 1 of 1
    # Warmup Iteration   1: <failure>
    
    com.fasterxml.jackson.core.JsonParseException: N/A
        at com.fasterxml.jackson.dataformat.xml.util.StaxUtil.throwAsParseException(StaxUtil.java:37)
        at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:534)
        at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:29)
        at com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:820)
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   devops    7 年前

    System.out.println("method call");

    > # Run progress: 0,00% complete, ETA 00:00:11
    > # Fork: 1 of 1
    > # Warmup Iteration   1: method call 
    > method call
    > <failure>
    

    objectMapper.readValue(..)

    @Param( { "1.xml", "10.xml", "100.xml" } )
    String file;
    
    private String jsonData;
    
    @Setup
    public void setup() {
        jsonData = getContent(file);
    }
    
    @Benchmark
    public void jacksonDeserializeStreamTest(Blackhole bh) throws IOException {
        bh.consume(objectMapper.readValue(jsonData, Cat.class));
    }
    
    private static String getContent(String fileName) {
        try {
            InputStream stream = PersonGenerator.class.getClassLoader().getResourceAsStream(fileName);
            ByteArrayOutputStream result = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int length;
            while ((length = stream.read(buffer)) != -1) {
                result.write(buffer, 0, length);
            }
            return result.toString("UTF-8");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    

    Gson-vs-Jackson-Benchmark

    Java I/O - Reuse InputStream Object

    String rawData = getContent("cats.json");
    StringReader reader = new StringReader(rawData);
    
    [...]
    reader.mark(0); // reset
    m.readValue(reader, type);
    [...]
    
    推荐文章