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.Base64InputStream;
031    import org.apache.james.mime4j.codec.CodecUtil;
032    
033    public class Base64InputStreamBench {
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 Base64InputStream(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 Base64InputStream(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.encodeBase64(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 Base64InputStream(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    }