Java 在JMH@Setup中初始化FileInputStream并在@Benchmark中使用
在Java 在JMH@Setup中初始化FileInputStream并在@Benchmark中使用,java,benchmarking,microbenchmark,jmh,Java,Benchmarking,Microbenchmark,Jmh,在@Benchmark中尝试使用时,在@Setup中初始化了InputStream,它已关闭。更改@状态无效。我这样做对吗?有没有办法避免流初始化开销并进行适当的基准测试 这不适用于XMLStreamReader此外,我正在做一个序列化-反序列化基准测试,我希望在基准测试分数中避免文件读取/流初始化成本 样本基准 @State( Scope.Thread ) public class DeserializationBenchMark { @Param( { "1.xml", "10.xm
@Benchmark
中尝试使用时,在@Setup
中初始化了InputStream
,它已关闭。更改@状态
无效。我这样做对吗?有没有办法避免流初始化开销并进行适当的基准测试
这不适用于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
任何建议都很好!多谢各位
附言:
正如@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)
#运行进度:完成0.00%,预计到达时间00:07:30
#叉子:1/1
#预热迭代1:
com.fasterxml.jackson.core.JsonParseException:不适用
位于com.fasterxml.jackson.dataformat.xml.util.StaxUtil.throwAsParseException(StaxUtil.java:37)
位于com.fasterxml.jackson.dataformat.xml.XmlFactory.\u createParser(XmlFactory.java:534)
位于com.fasterxml.jackson.dataformat.xml.XmlFactory.\u createParser(XmlFactory.java:29)
位于com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:820)
TL;博士
问题是第一次热身方法调用成功,但下一次调用失败。尝试添加System.out.println(“方法调用”)代码>你会看到我遇到了什么:
> # Run progress: 0,00% complete, ETA 00:00:11
> # Fork: 1 of 1
> # Warmup Iteration 1: method call
> method call
> <failure>
您可以尝试类似的基准测试:
编辑
很遗憾,您不能使用多个InputStream:
但也许您可以尝试以下(伪代码!):
你说的是对的。但我不明白为什么它在第一次迭代时失败。也许我应该更新这个问题。我想为readValue
传递另一个流。在第一次迭代结束后,String
@RuwankaMadhushan有单独的基准。每个@Benchmark
调用一次安装程序是的,您的完全正确,这就是这里应该发生的事情。但我无法找到它在第一次迭代时失败的原因。请看更新的问题。问题是第一次预热方法调用成功。尝试添加System.out.println(“方法调用”)你会看到我遇到了什么。我更新了我的答案。谢谢@dit我会找到一个解决方法,可能是您指出的:-)
@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);
}
}
String rawData = getContent("cats.json");
StringReader reader = new StringReader(rawData);
[...]
reader.mark(0); // reset
m.readValue(reader, type);
[...]