1
/****************************************************************
2
* Licensed to the Apache Software Foundation (ASF) under one *
3
* or more contributor license agreements. See the NOTICE file *
4
* distributed with this work for additional information *
5
* regarding copyright ownership. The ASF licenses this file *
6
* to you under the Apache License, Version 2.0 (the *
7
* "License"); you may not use this file except in compliance *
8
* with the License. You may obtain a copy of the License at *
10
* http://www.apache.org/licenses/LICENSE-2.0 *
12
* Unless required by applicable law or agreed to in writing, *
13
* software distributed under the License is distributed on an *
14
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
15
* KIND, either express or implied. See the License for the *
16
* specific language governing permissions and limitations *
17
* under the License. *
18
****************************************************************/
20
package org.apache.james.mime4j;
22
import java.io.ByteArrayInputStream;
23
import java.io.ByteArrayOutputStream;
24
import java.io.IOException;
25
import java.io.InputStream;
27
import org.apache.james.mime4j.codec.CodecUtil;
28
import org.apache.james.mime4j.dom.Header;
29
import org.apache.james.mime4j.dom.MessageBuilder;
30
import org.apache.james.mime4j.message.DefaultMessageBuilder;
31
import org.apache.james.mime4j.message.SimpleContentHandler;
32
import org.apache.james.mime4j.parser.AbstractContentHandler;
33
import org.apache.james.mime4j.parser.ContentHandler;
34
import org.apache.james.mime4j.parser.MimeStreamParser;
35
import org.apache.james.mime4j.storage.DefaultStorageProvider;
36
import org.apache.james.mime4j.storage.MemoryStorageProvider;
37
import org.apache.james.mime4j.stream.BodyDescriptor;
38
import org.apache.james.mime4j.stream.EntityState;
39
import org.apache.james.mime4j.stream.MimeTokenStream;
41
public class LongMultipartReadBench {
43
public static void main(String[] args) throws Exception {
45
byte[] content = loadMessage("long-multipart.msg");
46
if (content == null) {
47
System.err.println("Test message not found");
51
int testNumber = args.length > 0 ? Integer.parseInt(args[0]) : 0;
53
Test test = createTest(testNumber);
55
System.err.println("No such test: " + testNumber);
59
int repetitions = args.length > 1 ? Integer.parseInt(args[1]) : 25000;
61
System.out.println("Multipart message read.");
62
System.out.println("No of repetitions: " + repetitions);
63
System.out.println("Content length: " + content.length);
64
System.out.println("Test: " + test.getClass().getSimpleName());
66
System.out.print("Warmup... ");
67
long t0 = System.currentTimeMillis();
68
while (System.currentTimeMillis() - t0 < 1500) {
69
test.run(content, 10);
71
System.out.println("done");
73
System.out.println("--------------------------------");
75
long start = System.currentTimeMillis();
76
test.run(content, repetitions);
77
long finish = System.currentTimeMillis();
79
double seconds = (finish - start) / 1000.0;
80
double mb = content.length * repetitions / 1024.0 / 1024;
81
System.out.printf("Execution time: %f sec\n", seconds);
82
System.out.printf("%.2f messages/sec\n", repetitions / seconds);
83
System.out.printf("%.2f mb/sec\n", mb / seconds);
86
private static Test createTest(int testNumber) {
89
return new MimeTokenStreamTest();
91
return new AbstractContentHandlerTest();
93
return new SimpleContentHandlerTest();
95
return new MessageTest();
101
private static byte[] loadMessage(String resourceName) throws IOException {
102
ClassLoader cl = LongMultipartReadBench.class.getClassLoader();
104
ByteArrayOutputStream outstream = new ByteArrayOutputStream();
105
InputStream instream = cl.getResourceAsStream(resourceName);
106
if (instream == null) {
110
CodecUtil.copy(instream, outstream);
115
return outstream.toByteArray();
118
private interface Test {
119
void run(byte[] content, int repetitions) throws Exception;
122
private static final class MimeTokenStreamTest implements Test {
123
public void run(byte[] content, int repetitions) throws Exception {
124
MimeTokenStream stream = new MimeTokenStream();
125
for (int i = 0; i < repetitions; i++) {
126
stream.parse(new ByteArrayInputStream(content));
127
for (EntityState state = stream.getState(); state != EntityState.T_END_OF_STREAM; state = stream
134
private static final class AbstractContentHandlerTest implements Test {
135
public void run(byte[] content, int repetitions) throws Exception {
136
ContentHandler contentHandler = new AbstractContentHandler() {
139
for (int i = 0; i < repetitions; i++) {
140
MimeStreamParser parser = new MimeStreamParser();
141
parser.setContentHandler(contentHandler);
142
parser.parse(new ByteArrayInputStream(content));
147
private static final class SimpleContentHandlerTest implements Test {
148
public void run(byte[] content, int repetitions) throws Exception {
149
ContentHandler contentHandler = new SimpleContentHandler() {
151
public void body(BodyDescriptor bd, InputStream is)
153
byte[] b = new byte[4096];
154
while (is.read(b) != -1);
158
public void headers(Header header) {
162
for (int i = 0; i < repetitions; i++) {
163
MimeStreamParser parser = new MimeStreamParser();
164
parser.setContentDecoding(true);
165
parser.setContentHandler(contentHandler);
166
parser.parse(new ByteArrayInputStream(content));
171
private static final class MessageTest implements Test {
172
public void run(byte[] content, int repetitions) throws Exception {
173
DefaultStorageProvider.setInstance(new MemoryStorageProvider());
174
MessageBuilder builder = new DefaultMessageBuilder();
176
for (int i = 0; i < repetitions; i++) {
177
builder.parseMessage(new ByteArrayInputStream(content));
183
// requires mail.jar and activation.jar to be present
184
private static final class MimeMessageTest implements Test {
185
public void run(byte[] content, int repetitions) throws Exception {
186
for (int i = 0; i < repetitions; i++) {
187
MimeMessage mm = new MimeMessage(null, new ByteArrayInputStream(content));
188
Multipart multipart = (Multipart) mm.getContent();
189
multipart.getCount(); // force parsing