Question

I have a class that creates a random string based on BigInteger. All works fine and efficient when run standalone (Windows, 22ms).

private SecureRandom random = new SecureRandom();

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

When this code is put into a library (jar) and called from Coldfusion (9.0.2), this code hangs for 1 to 1.5 minutes (on my server, linux). This code is called from a cfc:

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

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

What am I missing?

Was it helpful?

Solution

I am just astonished that the difference was not noticable on my Windows box.

There are different SecureRandom strategies. On window it could be using a random seed based on the host name, which for windows can wander off to a DNS to get a reverse lookup the first time. This can time out the request after a minute or so.

I would ensure you have a recent update of Java because I believe this is a problem which was fixed in some update of Java 6. (Not to do with SecureRandom, but with first network operation being incredibly slow)

BTW This was tested on a Windows 7 box and the first time, it hung for a few seconds, but not after that.


If your code is hanging to 60 to 90 seconds, it is not due to this method, far more likely you are performing a GC, and this method is stopping because it allocated memory.


While BigInteger is slow, SecureRandom is much, much slower. If you want this to be faster, use plain Random.

It would be slightly faster if you used less bits.

BTW I would use base 36 (the maximum), rather than base 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());
    }
}

prints

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

The time to generate the string is significant, but still no where near enough to cause a multi-second delay.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top