To Pool or not to Pool java crypto service providers

后端 未结 2 1350
一个人的身影
一个人的身影 2021-02-01 09:58

Solution

  • MessageDigest => create new instances as often as needed
  • KeyFactory => use a single shared instance
  • SecureRandom => use a StackObject
相关标签:
2条回答
  • 2021-02-01 10:11

    If you give 100 threads access to a shared MessageDigest and get them to calculate 1,000,000 hashes each then on my machine the first thread finishes in 70,160ms and the last finishes in 98,748ms.

    If the threads create a new instance of MessageDigest each time, then the first thread finishes in 43,392ms and the last 58,691ms.

    Edit:
    In fact with this example, with only two threads the example creating new instances runs quicker.

    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class Share {
    
      final byte[] bytes = new byte[100];
      final MessageDigest sharedDigest;
      final ExecutorService pool;
      int threads = 100;
    
      Share() throws NoSuchAlgorithmException {
        sharedDigest = MessageDigest.getInstance("MD5");
        pool = Executors.newFixedThreadPool(threads);
      }
    
      void go() {
    
        for (int i=0; i<threads; i++) {
          pool.execute(new Runnable() {
            public void run() {
              long start = System.currentTimeMillis();
              for (int i=0; i<1000000; i++) {
                /*
                synchronized (sharedDigest) {
                  sharedDigest.reset();
                  sharedDigest.update(bytes);
                  sharedDigest.digest();
                }*/
                try {
                  MessageDigest digest = MessageDigest.getInstance("MD5");
                  digest.reset();
                  digest.update(bytes);
                  digest.digest();
                } catch (Exception ex) {
                  ex.printStackTrace();
                }
              }
              long end = System.currentTimeMillis();
              System.out.println(end-start);
              pool.shutdown();
            }
          });
        }
    
      }
    
      public static void main(String[] args) throws Exception {
        Share share = new Share();
        share.go();
      }
    
    }
    
    0 讨论(0)
  • 2021-02-01 10:14

    This test seems to be in favour of caching

    long t0 = System.currentTimeMillis();
    byte[] bytes = new byte[100];
    MessageDigest md = MessageDigest.getInstance("MD5");
    for(int i = 0; i < 1000000; i++) {
        //MessageDigest md = MessageDigest.getInstance("MD5");
        md.reset();
        md.update(bytes);
        md.digest();
    }
    System.out.println(System.currentTimeMillis() - t0);
    

    When md is outside the loop it prints 579, when inside - 953.

    0 讨论(0)
提交回复
热议问题