1

我有一个基于 BigInteger 创建随机字符串的类。独立运行(Windows,22ms)时一切正常且高效。

private SecureRandom random = new SecureRandom();

public String testMe() {
     return new BigInteger(130, random).toString(30)
}

当将此代码放入库 (jar) 并从 Coldfusion (9.0.2) 调用时,此代码会挂起 1 到 1.5 分钟(在我的服务器 linux 上)。此代码是从 cfc 调用的:

<cfset myTest = CreateObject("java", "com.acme.MyTest")>

<cffunction name="runTest" access="public">
    <cfset var value = myTest.testMe()/>
</cffunction>

我错过了什么?

4

1 回答 1

3

我只是惊讶于我的 Windows 机器上的差异并不明显。

有不同的 SecureRandom 策略。在窗口上,它可能使用基于主机名的随机种子,对于 Windows 来说,它可以在第一次访问 DNS 以进行反向查找。这可能会在一分钟左右后使请求超时。

我会确保您最近更新了 Java,因为我相信这是在 Java 6 的某些更新中修复的问题。(与 SecureRandom 无关,但第一次网络操作非常慢)

顺便说一句,这是在 Windows 7 机器上测试的,第一次,它挂了几秒钟,但在那之后就没有了。


如果您的代码挂起到 60 到 90 秒,则不是由于此方法,更有可能是您正在执行 GC,并且此方法正在停止,因为它分配了内存。


虽然 BigInteger 很慢,但 SecureRandom 慢得多。如果您希望它更快,请使用纯随机。

如果你使用更少的位,它会稍微快一点。

顺便说一句,我会使用基数 36(最大值),而不是基数 30。

static volatile String dontOptimiseAway = null;
public static void testRandomBigInteger(Random random) {
    long start = System.nanoTime();
    int runs = 10000;
    for(int i=0;i< runs;i++) {
        dontOptimiseAway = new BigInteger(130, random).toString(36);
    }
    long time = System.nanoTime() - start;
    System.out.printf("%s took %.1f micro-seconds on average%n", random.getClass().getSimpleName(), time/runs/1e3);
}
public static void main(String... ignored) {
    for (int i = 0; i < 10; i++) {
        testRandomBigInteger(new Random());
        testRandomBigInteger(new SecureRandom());
    }
}

印刷

Random took 1.7 micro-seconds on average
SecureRandom took 2.1 micro-seconds on average

生成字符串的时间很长,但仍远不足以导致多秒延迟。

于 2013-08-12T17:44:49.567 回答