我有一个基于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>
我错过了什么?
答案 0 :(得分:3)
我很惊讶我的Windows机箱上的差异并不明显。
有不同的SecureRandom策略。在窗口上,它可以使用基于主机名的随机种子,对于Windows,它可以漫游到DNS以便第一次进行反向查找。这可能会在一分钟左右后超时请求。
我会确保您最近更新了Java,因为我认为这是一个在Java 6的某些更新中修复的问题。(与SecureRandom无关,但第一次网络操作非常慢)
BTW这是在Windows 7机箱上测试的,第一次,它挂了几秒钟,但之后没有。
如果您的代码挂起60到90秒,则不是由于这种方法,更有可能是您执行GC,并且此方法因为分配内存而停止。
虽然BigInteger很慢,但SecureRandom要慢很多。如果您希望更快,请使用普通随机。
如果你使用较少的比特,会稍快一些。
BTW我会使用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
生成字符串的时间非常重要,但仍然没有足够接近导致多秒延迟的时间。