This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-mime4j.git
commit 53ccf4631a62eeb3121c2a47fa9fba6172320215 Author: Benoit Tellier <btell...@linagora.com> AuthorDate: Mon Jun 20 15:13:04 2022 +0700 MIME4J-317 Example of MIME4 benchmark using JMH --- benchmark/pom.xml | 14 ++ .../james/mime4j/JMHLongMultipartReadBench.java | 144 +++++++++++++++++++++ core/pom.xml | 1 + mbox/pom.xml | 1 + pom.xml | 1 - storage/pom.xml | 1 + 6 files changed, 161 insertions(+), 1 deletion(-) diff --git a/benchmark/pom.xml b/benchmark/pom.xml index 773c7710..3995563b 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -34,6 +34,20 @@ <description>Benchmarks for MIME4J stream based MIME message parser</description> <dependencies> + <dependency> + <groupId>org.openjdk.jmh</groupId> + <artifactId>jmh-core</artifactId> + <version>1.21</version> + </dependency> + <dependency> + <groupId>org.openjdk.jmh</groupId> + <artifactId>jmh-generator-annprocess</artifactId> + <version>1.21</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> <dependency> <groupId>org.apache.james</groupId> <artifactId>apache-mime4j-dom</artifactId> diff --git a/benchmark/src/main/java/org/apache/james/mime4j/JMHLongMultipartReadBench.java b/benchmark/src/main/java/org/apache/james/mime4j/JMHLongMultipartReadBench.java new file mode 100644 index 00000000..f2521fd6 --- /dev/null +++ b/benchmark/src/main/java/org/apache/james/mime4j/JMHLongMultipartReadBench.java @@ -0,0 +1,144 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.mime4j; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.TimeUnit; + +import org.apache.james.mime4j.dom.Header; +import org.apache.james.mime4j.dom.MessageBuilder; +import org.apache.james.mime4j.message.DefaultMessageBuilder; +import org.apache.james.mime4j.message.SimpleContentHandler; +import org.apache.james.mime4j.parser.AbstractContentHandler; +import org.apache.james.mime4j.parser.ContentHandler; +import org.apache.james.mime4j.parser.MimeStreamParser; +import org.apache.james.mime4j.stream.BodyDescriptor; +import org.apache.james.mime4j.stream.EntityState; +import org.apache.james.mime4j.stream.MimeTokenStream; +import org.apache.james.mime4j.util.ContentUtil; +import org.junit.Test; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.profile.GCProfiler; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; +import org.openjdk.jmh.runner.options.TimeValue; + +public class JMHLongMultipartReadBench { + private static final byte[] CONTENT = loadMessage("long-multipart.msg"); + + @Test + public void launchBenchmark() throws Exception { + Options opt = new OptionsBuilder() + // Specify which benchmarks to run. + // You can be more specific if you'd like to run only one benchmark per test. + .include(this.getClass().getName() + ".*") + // Set the following options as needed + .mode (Mode.AverageTime) + .addProfiler(GCProfiler.class) + .timeUnit(TimeUnit.MICROSECONDS) + .warmupTime(TimeValue.seconds(5)) + .warmupIterations(2) + .measurementTime(TimeValue.seconds(5)) + .measurementIterations(5) + .threads(1) + .forks(1) + .shouldFailOnError(true) + .shouldDoGC(true) + .build(); + + new Runner(opt).run(); + } + + private static byte[] loadMessage(String resourceName) { + try { + ClassLoader cl = JMHLongMultipartReadBench.class.getClassLoader(); + + ByteArrayOutputStream outstream = new ByteArrayOutputStream(); + InputStream instream = cl.getResourceAsStream(resourceName); + if (instream == null) { + return null; + } + try { + ContentUtil.copy(instream, outstream); + } finally { + instream.close(); + } + + return outstream.toByteArray(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Benchmark + public void benchmark1(Blackhole bh) throws Exception{ + MimeTokenStream stream = new MimeTokenStream(); + stream.parse(new ByteArrayInputStream(CONTENT)); + for (EntityState state = stream.getState(); state != EntityState.T_END_OF_STREAM; state = stream + .next()) { + } + stream.stop(); + } + + @Benchmark + public void benchmark2(Blackhole bh) throws Exception{ + ContentHandler contentHandler = new AbstractContentHandler() { + }; + + MimeStreamParser parser = new MimeStreamParser(); + parser.setContentHandler(contentHandler); + parser.parse(new ByteArrayInputStream(CONTENT)); + parser.stop(); + } + + @Benchmark + public void benchmark3(Blackhole bh) throws Exception{ + ContentHandler contentHandler = new SimpleContentHandler() { + @Override + public void body(BodyDescriptor bd, InputStream is) + throws IOException { + byte[] b = new byte[4096]; + while (is.read(b) != -1); + } + + @Override + public void headers(Header header) { + } + }; + + MimeStreamParser parser = new MimeStreamParser(); + parser.setContentDecoding(true); + parser.setContentHandler(contentHandler); + parser.parse(new ByteArrayInputStream(CONTENT)); + parser.stop(); + } + + @Benchmark + public void benchmark4(Blackhole bh) throws Exception{ + MessageBuilder builder = new DefaultMessageBuilder(); + builder.parseMessage(new ByteArrayInputStream(CONTENT)); + } +} diff --git a/core/pom.xml b/core/pom.xml index 8603344f..216e1eb5 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -36,6 +36,7 @@ <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> + <scope>test</scope> </dependency> <dependency> <groupId>commons-io</groupId> diff --git a/mbox/pom.xml b/mbox/pom.xml index ad56e0cc..6a5bacad 100644 --- a/mbox/pom.xml +++ b/mbox/pom.xml @@ -37,6 +37,7 @@ <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> + <scope>test</scope> </dependency> </dependencies> diff --git a/pom.xml b/pom.xml index cffc4ca4..6dec3ea9 100644 --- a/pom.xml +++ b/pom.xml @@ -124,7 +124,6 @@ <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> - <scope>test</scope> </dependency> <dependency> <groupId>org.assertj</groupId> diff --git a/storage/pom.xml b/storage/pom.xml index 082826f4..563eb0d9 100644 --- a/storage/pom.xml +++ b/storage/pom.xml @@ -45,6 +45,7 @@ <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> + <scope>test</scope> </dependency> </dependencies> --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org