`
deepinmind
  • 浏览: 444590 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
1dc14e59-7bdf-33ab-841a-02d087aed982
Java函数式编程
浏览量:40798
社区版块
存档分类
最新评论

Java 8之base64

 
阅读更多

Java 8最终还是发布了。现在终于有了标准的方法来处理base64的编解码。很长时间以来我们都得依赖于Apache Commons Codec(当然它也是相当棒的)。比较在乎内存开销的开发人员通常会单独使用sun.misc.BASE64Encoder和sun.misc.BASE64Decoder,这样避免了加载额外的JAR包到应用程序里面,当然前提是他们确定他们用的一定就是SUN/Oracle的JDK。这些类在Java 8里依然存在。

这里写了个JUnit测试程序来演示下如何使用这几种API来进行base64编码:
  • Commons Codec: org.apache.commons.codec.binary.Base64
  • Java 8′s new java.util.Base64
  • The sort-of evergreen internal code of Sun/Oracle’s JDK: sun.misc.BASE64Encoder

  • package org.gizmo.util;
    
    import java.util.Random;
    
    import org.apache.commons.codec.binary.Base64;
    import org.junit.AfterClass;
    import org.junit.BeforeClass;
    import org.junit.Test;
    import static org.junit.Assert.assertArrayEquals;
    
    import sun.misc.BASE64Encoder;
    
    public class Base64Tests {
    
     private static byte[] randomBinaryData = new byte[5000000];
     private static long durationCommons = 0;
     private static long durationJava8 = 0;
     private static long durationSun = 0;
    
     private static byte[] encodedCommons;
     private static byte[] encodedJava8;
     private static String encodedSun;
    
     @BeforeClass
     public static void setUp() throws Exception {
    
      //We want to test the APIs against the same data
      new Random().nextBytes(randomBinaryData);  
     }
    
     @Test
     public void testSunBase64Encode() throws Exception {
    
      BASE64Encoder encoder = new BASE64Encoder();
    
      long before = System.currentTimeMillis();
    
      encodedSun = encoder.encode(randomBinaryData);
    
      long after = System.currentTimeMillis();
      durationSun = after-before;
      System.out.println("Sun: " + durationSun);
     } 
    
     @Test
     public void testJava8Base64Encode() throws Exception {
    
      long before = System.currentTimeMillis();
    
      java.util.Base64.Encoder encoder = java.util.Base64.getEncoder();
      encodedJava8 = encoder.encode(randomBinaryData);
    
      long after = System.currentTimeMillis();
      durationJava8 = after-before;
      System.out.println("Java8: " + durationJava8);
     }
    
     @Test
     public void testCommonsBase64Encode() throws Exception {
    
      long before = System.currentTimeMillis();
    
      encodedCommons = Base64.encodeBase64(randomBinaryData);
    
      long after = System.currentTimeMillis();
      durationCommons = after-before;
      System.out.println("Commons: " + durationCommons);
     }
    
     @AfterClass
     public static void report() throws Exception {
    
      //Sanity check
      assertArrayEquals(encodedCommons, encodedJava8);
      System.out.println(durationCommons*1.0/durationJava8);
     }
    }
    
    


    这三种方式的性能到底如何呢?看起来base64只是个很小的方法,因为它把程序拖垮的可能性不大,不过你永远不知道底下到底藏着些什么。这里简单的测试了一下时间,从结果来看,这三种方式按从快到慢是这个顺序:Java 8, Commons, Sun。下面是测试的结果(对长度为5000000的字节数组进行编码):

    +Sun: 521
    +Commons: 160
    +Java8: 37

    Java 8的性能是Commons的四倍,是Sun的14倍。不过这个测试有点简单,你最好自己做下基准测试来得出你自己的结论。

    那么,到底该用哪种方式呢?专家们通常会这么说——这得分情况。如果确定你的代码是跑在Java 8及以上的版本,那么就用新的java.util.Base64吧。如果你需要支持多种不同的Jdk版本的话,最好是使用commons或者别的第三方库。或者就等老的版本的java不再使用了,你再重写你的代码。再或者就是,换一种编程语言来实现吧。

    注意:我甚至都没提到用sun.misc.BASE64Encoder。尽量别去用它。也许有一天某个版本的JDK就会删掉它。并且别的厂商发布的JDK里也没有这个类。

    原创文章转载请注明出处:http://it.deepinmind.com

    英文原文链接




    3
    0
    分享到:
    评论
    2 楼 foxsky 2014-04-06  
    谢谢,确实比自己写的速度快。
    1 楼 jahu 2014-04-06  
    Commons 做了重复操作,所以慢了,

    相关推荐

    Global site tag (gtag.js) - Google Analytics