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
020 package org.apache.james.mime4j;
021
022 import java.io.ByteArrayInputStream;
023 import java.io.ByteArrayOutputStream;
024 import java.io.IOException;
025 import java.io.InputStream;
026 import java.io.OutputStream;
027 import java.util.Random;
028
029 import org.apache.commons.io.output.NullOutputStream;
030 import org.apache.james.mime4j.codec.CodecUtil;
031 import org.apache.james.mime4j.codec.QuotedPrintableInputStream;
032
033 public class QuotedPrintableInputStreamBench {
034
035 public static void main(String[] args) throws Exception {
036 byte[] data = initData(2 * 1024 * 1024);
037 byte[] encoded = encode(data);
038
039 // decoder test to make sure everything is okay
040
041 testDecode(data, encoded);
042
043 // warmup
044
045 OutputStream nullOut = new NullOutputStream();
046
047 for (int i = 0; i < 5; i++) {
048 ByteArrayInputStream ed = new ByteArrayInputStream(encoded);
049 InputStream in = new QuotedPrintableInputStream(ed);
050 CodecUtil.copy(in, nullOut);
051 }
052 Thread.sleep(100);
053
054 // test
055
056 long t0 = System.currentTimeMillis();
057
058 final int repetitions = 50;
059 for (int i = 0; i < repetitions; i++) {
060 ByteArrayInputStream ed = new ByteArrayInputStream(encoded);
061 InputStream in = new QuotedPrintableInputStream(ed);
062 CodecUtil.copy(in, nullOut);
063 }
064
065 long dt = System.currentTimeMillis() - t0;
066 long totalBytes = data.length * (long) repetitions;
067
068 double mbPerSec = (totalBytes / 1024.0 / 1024) / (dt / 1000.0);
069
070 System.out.println(dt + " ms");
071 System.out.println(totalBytes + " bytes");
072 System.out.println(mbPerSec + " mb/sec");
073 }
074
075 private static byte[] initData(int size) {
076 Random random = new Random(size);
077 byte[] data = new byte[size];
078 random.nextBytes(data);
079 return data;
080 }
081
082 private static byte[] encode(byte[] data) throws IOException {
083 InputStream in = new ByteArrayInputStream(data);
084 ByteArrayOutputStream out = new ByteArrayOutputStream();
085 CodecUtil.encodeQuotedPrintableBinary(in, out);
086 return out.toByteArray();
087 }
088
089 private static void testDecode(byte[] data, final byte[] encoded)
090 throws IOException {
091 ByteArrayInputStream ed = new ByteArrayInputStream(encoded);
092 InputStream in = new QuotedPrintableInputStream(ed);
093 ByteArrayOutputStream out = new ByteArrayOutputStream();
094 CodecUtil.copy(in, out);
095
096 compare(data, out.toByteArray());
097 }
098
099 private static void compare(byte[] expected, byte[] actual) {
100 if (expected.length != actual.length)
101 throw new AssertionError("length: " + expected.length + ", "
102 + actual.length);
103
104 for (int i = 0; i < expected.length; i++)
105 if (expected[i] != actual[i])
106 throw new AssertionError("value @ " + i);
107 }
108
109 }