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 に移動する可能性があります。これにより、1 分ほどでリクエストがタイムアウトする可能性があります。

これは Java 6 の更新で修正された問題だと思うので、Java の最新の更新があることを確認します (SecureRandom とは関係ありませんが、最初のネットワーク操作が非常に遅いため)。

ところで、これは Windows 7 ボックスでテストされ、最初は数秒間ハングしましたが、その後はハングしませんでした。


コードが 60 ~ 90 秒ハングする場合、それはこのメソッドが原因ではなく、GC を実行している可能性がはるかに高く、このメソッドはメモリを割り当てたために停止しています。


BigInteger は遅いですが、SecureRandom は非常に遅いです。これをより速くしたい場合は、プレーン Random を使用してください。

使用するビット数が少ないと、わずかに高速になります。

ところで、基数 30 ではなく、基数 36 (最大値) を使用します。

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 に答える