0

Why the first call of of encryption take hundred time of the second one

byte[] key = //... secret sequence of bytes
byte[] dataToSend = ...

Here's my encryption method:

public static byte[] enc(byte data[], byte key[]
{
Cipher c = Cipher.getInstance("AES");
SecretKeySpec k =
  new SecretKeySpec(key, "AES");
c.init(Cipher.ENCRYPT_MODE, k);
byte[] encryptedData = c.doFinal(dataToSend);
return encryptedData;
}

and here is the test code

byte [] key="1111111111111111".toByteArray();
byte [] data=new byte [32];
for(int i=0;i<1000;i++)
{
long x=System.nanoTime();
enc(data,key);
System.out.println(System.nanoTime()-x);

}

The first value will be something like 20300, then the other value will drop to 50 , 35 , 42 ..etc If its something that need loading can i do this before starting the application . I am working in network protocol and need to do benchmark with another one.

Milen
  • 8,697
  • 7
  • 43
  • 57
primeFaceUser
  • 295
  • 2
  • 15
  • this code is not copy paste . i have written this code here so compilation error my exist – primeFaceUser Jun 14 '13 at 07:15
  • 3
    `The first value will be something like 20300, then the other value will drop to 50 , 35 , 42` - you might need to get familiar with JVM warmup and caching effects – Andreas Fester Jun 14 '13 at 07:17
  • 2
    Chances are that the entire set of classes required for AES get loaded in the first iteration. That would also explain part of the huge difference. – Joachim Sauer Jun 14 '13 at 07:18
  • so setting the Cipher to a static global variable will help removing this problem. – primeFaceUser Jun 14 '13 at 07:22
  • If you want to do benchmarking as accurate as possible, consider using [caliper](http://code.google.com/p/caliper/) – fge Jun 14 '13 at 07:29
  • Please note that the AES key expansion routines may take a relatively long time. You are better off reusing the same cipher object, especially if the key does not change. I'm not sure what happens if you re-initialize with a different IV though. Currently you are not using an IV but the rather unsafe ECB mode of operation. – Maarten Bodewes Jun 14 '13 at 10:56

1 Answers1

2

The first value will be something like 20300, then the other value will drop to 50 , 35 , 42

When doing benchmarking, you need to consider some effects of the execution environment which take place in the background, such as

  • Caching effects (both at the CPU level at the runtime library level)
  • Warmup effects - in particular for Java, the JIT compiler does not necessarily compile all byte code into native code the first time it is executed, but only when the same code is executed multiple times.

In general, you need to execute your code several times before you start the benchmarking so that these effects do not affect the actual measurement results.

See also

Community
  • 1
  • 1
Andreas Fester
  • 36,091
  • 7
  • 95
  • 123
  • 1
    Thanks, this is great info. A similar post on [avoid jvm warmup](http://stackoverflow.com/questions/4345999/avoid-jvm-warmup) can be referred for further understanding. – asgs Jun 14 '13 at 07:25
  • I am making 5 experiment of 1000 request/reply to my protocol . also both protocols are written on java. – primeFaceUser Jun 14 '13 at 07:29