001/**************************************************************** 002 * Licensed to the Apache Software Foundation (ASF) under one * 003 * or more contributor license agreements. See the NOTICE file * 004 * distributed with this work for additional information * 005 * regarding copyright ownership. The ASF licenses this file * 006 * to you under the Apache License, Version 2.0 (the * 007 * "License"); you may not use this file except in compliance * 008 * with the License. You may obtain a copy of the License at * 009 * * 010 * http://www.apache.org/licenses/LICENSE-2.0 * 011 * * 012 * Unless required by applicable law or agreed to in writing, * 013 * software distributed under the License is distributed on an * 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * 015 * KIND, either express or implied. See the License for the * 016 * specific language governing permissions and limitations * 017 * under the License. * 018 ****************************************************************/ 019 020package org.apache.james.mime4j; 021 022import java.io.ByteArrayInputStream; 023import java.io.ByteArrayOutputStream; 024import java.io.IOException; 025import java.io.InputStream; 026 027import org.apache.james.mime4j.codec.CodecUtil; 028import org.apache.james.mime4j.dom.Header; 029import org.apache.james.mime4j.dom.MessageBuilder; 030import org.apache.james.mime4j.message.DefaultMessageBuilder; 031import org.apache.james.mime4j.message.SimpleContentHandler; 032import org.apache.james.mime4j.parser.AbstractContentHandler; 033import org.apache.james.mime4j.parser.ContentHandler; 034import org.apache.james.mime4j.parser.MimeStreamParser; 035import org.apache.james.mime4j.storage.DefaultStorageProvider; 036import org.apache.james.mime4j.storage.MemoryStorageProvider; 037import org.apache.james.mime4j.stream.BodyDescriptor; 038import org.apache.james.mime4j.stream.EntityState; 039import org.apache.james.mime4j.stream.MimeTokenStream; 040 041public class LongMultipartReadBench { 042 043 public static void main(String[] args) throws Exception { 044 045 byte[] content = loadMessage("long-multipart.msg"); 046 if (content == null) { 047 System.err.println("Test message not found"); 048 return; 049 } 050 051 int testNumber = args.length > 0 ? Integer.parseInt(args[0]) : 0; 052 053 Test test = createTest(testNumber); 054 if (test == null) { 055 System.err.println("No such test: " + testNumber); 056 return; 057 } 058 059 int repetitions = args.length > 1 ? Integer.parseInt(args[1]) : 25000; 060 061 System.out.println("Multipart message read."); 062 System.out.println("No of repetitions: " + repetitions); 063 System.out.println("Content length: " + content.length); 064 System.out.println("Test: " + test.getClass().getSimpleName()); 065 066 System.out.print("Warmup... "); 067 long t0 = System.currentTimeMillis(); 068 while (System.currentTimeMillis() - t0 < 1500) { 069 test.run(content, 10); 070 } 071 System.out.println("done"); 072 073 System.out.println("--------------------------------"); 074 075 long start = System.currentTimeMillis(); 076 test.run(content, repetitions); 077 long finish = System.currentTimeMillis(); 078 079 double seconds = (finish - start) / 1000.0; 080 double mb = content.length * repetitions / 1024.0 / 1024; 081 System.out.printf("Execution time: %f sec\n", seconds); 082 System.out.printf("%.2f messages/sec\n", repetitions / seconds); 083 System.out.printf("%.2f mb/sec\n", mb / seconds); 084 } 085 086 private static Test createTest(int testNumber) { 087 switch (testNumber) { 088 case 0: 089 return new MimeTokenStreamTest(); 090 case 1: 091 return new AbstractContentHandlerTest(); 092 case 2: 093 return new SimpleContentHandlerTest(); 094 case 3: 095 return new MessageTest(); 096 default: 097 return null; 098 } 099 } 100 101 private static byte[] loadMessage(String resourceName) throws IOException { 102 ClassLoader cl = LongMultipartReadBench.class.getClassLoader(); 103 104 ByteArrayOutputStream outstream = new ByteArrayOutputStream(); 105 InputStream instream = cl.getResourceAsStream(resourceName); 106 if (instream == null) { 107 return null; 108 } 109 try { 110 CodecUtil.copy(instream, outstream); 111 } finally { 112 instream.close(); 113 } 114 115 return outstream.toByteArray(); 116 } 117 118 private interface Test { 119 void run(byte[] content, int repetitions) throws Exception; 120 } 121 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 128 .next()) { 129 } 130 } 131 } 132 } 133 134 private static final class AbstractContentHandlerTest implements Test { 135 public void run(byte[] content, int repetitions) throws Exception { 136 ContentHandler contentHandler = new AbstractContentHandler() { 137 }; 138 139 for (int i = 0; i < repetitions; i++) { 140 MimeStreamParser parser = new MimeStreamParser(); 141 parser.setContentHandler(contentHandler); 142 parser.parse(new ByteArrayInputStream(content)); 143 } 144 } 145 } 146 147 private static final class SimpleContentHandlerTest implements Test { 148 public void run(byte[] content, int repetitions) throws Exception { 149 ContentHandler contentHandler = new SimpleContentHandler() { 150 @Override 151 public void body(BodyDescriptor bd, InputStream is) 152 throws IOException { 153 byte[] b = new byte[4096]; 154 while (is.read(b) != -1); 155 } 156 157 @Override 158 public void headers(Header header) { 159 } 160 }; 161 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)); 167 } 168 } 169 } 170 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(); 175 176 for (int i = 0; i < repetitions; i++) { 177 builder.parseMessage(new ByteArrayInputStream(content)); 178 } 179 } 180 } 181 182 /* 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 190 } 191 } 192 } 193 */ 194 195}