gpt4 book ai didi

java - 池化或不池化 java 加密服务提供者

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:59:25 24 4
gpt4 key购买 nike

解决方案

  • MessageDigest => 根据需要经常创建新实例
  • KeyFactory => 使用单个共享实例
  • SecureRandom => 使用 StackObjectPool
  • Cipher => 使用 StackObjectPool

问题

我在编写安全性框架时经常面临两难境地:“合并还是不合并”

基本上这个问题分为两个“组”:

  1. 第 1 组:SecureRandom 因为对 nextBytes(...) 的调用是同步的,它可能成为 Web 应用程序/多线程应用程序的瓶颈应用

  2. 第 2 组:MessageDigestSignatureCipherKeyFactory 等加密服务提供商。 ..(因为 getInstance() 的成本?)

你怎么看?

你对此类问题的习惯是什么?

编辑 09/07/2013

我终于抽出时间自己测试了@Qwerky Share 类,我发现结果相当......令人惊讶。

类(class)缺少我的主要关注点:像 GenericObjectPool 这样的池或 StackObjectPool .

所以我修改了类(class)以测试所有 4 个备选方案:

  • 具有同步功能的单个共享实例 gist
  • 每个循环内的新实例(我对可以将摘要创建拉到循环外的情况不感兴趣)gist
  • 通用对象池:gist
  • 堆栈对象池:gist

我不得不将循环数减少到 100000,因为 1M 占用了池太多时间。

我还在每个循环的末尾添加了一个 Thread.yield() 以使负载具有更好的形状。

结果(累计运行时间):

  • 消息摘要
    • 新实例:420 秒
    • 单个实例:550 秒
    • 堆栈对象池:800 秒
    • 通用对象池:1900 秒
  • key 工厂
    • 新实例:400 秒
    • 单个实例:350 秒
    • 堆栈对象池:2900 秒
    • 通用对象池:3500 秒
  • 安全随机
    • 堆栈对象池:1600 秒
    • 新实例:2300 秒
    • 通用对象池:2300s
    • 单个实例:2800 秒
  • 密码
    • 堆栈对象池:2800 秒
    • 通用对象池:3500 秒
    • 单个实例:5100 秒
    • 新实例:8000 秒

结论

对于 MessageDigest 和 KeyFactory,池是性能 killer ,甚至比具有同步瓶颈的单个实例更糟糕,而当涉及到 SecureRandom 和 Cipher 时,它们非常有用

最佳答案

如果您让 100 个线程访问共享的 MessageDigest 并让它们每个计算 1,000,000 个哈希值,那么在我的机器上,第一个线程在 70,160 毫秒内完成,最后一个线程在 98,748 毫秒内完成。

如果线程每次都创建一个新的 MessageDigest 实例,那么第一个线程将在 43,392 毫秒和最后一个线程中完成 58,691 毫秒。

编辑:
事实上,对于这个例子,只有两个线程,创建新实例的例子运行得更快。

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();
}

}

关于java - 池化或不池化 java 加密服务提供者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13913075/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com