dev@grizzly.java.net

Re: a question on enum performance

From: Scott Oaks <Scott.Oaks_at_Sun.COM>
Date: Wed, 12 Dec 2007 15:23:18 -0500

You're not actually measuring the difference between enum and int;
you're measuring the difference between a big switch statement and a
nested set of if statements.

If you recast the enum code to a set of if statements, you'll get the
same performance from it as from the int test. If you recast the test
int case to a switch instead of if statements, you won't see a
performance change from your original test (that is -- the testInt with
switch will still be faster than the testEnum with switch). The reason
for that is because Java has two kinds of switch statements, and in the
case of the integers, there is a well defined range of things so the
compiler will choose the faster switch statement. In the case of the
Enum, there's not a range, and it will use the oh-so-slightly slower
switch statement.

I have actually once run into a case where the slower switch statement
use measurably affected an actual application. But generally, I'd say
program the switch because it's easier to understand and maintain, and
if the performance ever becomes an issue, we'd address it then.

-Scott

On Wed, 2007-12-12 at 14:58, Shing-Wai.Chan_at_Sun.COM wrote:
> Hi,
>
> From code review comments, there is a concern about
> the performance of using enum.
> I have try to measure this by myself (see attached programs)
> and see the following:
>
> elliptic: /home/swchan2/doc/grizzly > java EnumTest
> time for int[10] (ms): 0
> time for type[10] (ms): 1
>
> time for int[100] (ms): 0
> time for type[100] (ms): 0
>
> time for int[1000] (ms): 0
> time for type[1000] (ms): 0
>
> time for int[10000] (ms): 2
> time for type[10000] (ms): 2
>
> time for int[100000] (ms): 0
> time for type[100000] (ms): 11
>
> time for int[1000000] (ms): 0
> time for type[1000000] (ms): 2
>
> time for int[10000000] (ms): 0
> time for type[10000000] (ms): 18
>
> There is no doubt that enum is a bit slower than using static final int.
> But is it significant?
> Should we avoid using enum in our code in this case?
> Any comment?
>
> Thanks.
> Shing Wai Chan
>
>
> ______________________________________________________________________
> import java.util.Random;
>
> public class EnumTest {
> public static enum Type {
> A,
> B,
> C,
> D,
> E,
> F,
> G,
> H,
> I,
> J
> }
>
> public static final int AA = 0;
> public static final int BB = 1;
> public static final int CC = 2;
> public static final int DD = 3;
> public static final int EE = 4;
> public static final int FF = 5;
> public static final int GG = 6;
> public static final int HH = 7;
> public static final int II = 8;
> public static final int JJ = 9;
>
> private static int[] genRandomInts(int count) {
> int[] is = new int[count];
> Random r = new Random();
> for (int i = 0; i < count; i++) {
> is[i] = r.nextInt(10);
> }
> return is;
> }
>
> private static Type[] genRandomTypes(int count) {
> Type[] ts = new Type[count];
> Random r = new Random();
> for (int i = 0; i < count; i++) {
> int temp = r.nextInt(10);
> if (temp == AA) {
> ts[i] = Type.A;
> } else if (temp == BB) {
> ts[i] = Type.B;
> } else if (temp == CC) {
> ts[i] = Type.C;
> } else if (temp == DD) {
> ts[i] = Type.D;
> } else if (temp == EE) {
> ts[i] = Type.E;
> } else if (temp == FF) {
> ts[i] = Type.F;
> } else if (temp == GG) {
> ts[i] = Type.G;
> } else if (temp == HH) {
> ts[i] = Type.H;
> } else if (temp == II) {
> ts[i] = Type.I;
> } else if (temp == JJ) {
> ts[i] = Type.J;
> }
> }
> return ts;
> }
>
> private static void testInt(int count) {
> int x = 0;
> int[] rs = genRandomInts(count);
>
> long t1 = System.currentTimeMillis();
> for (int r : rs) {
> if (r == AA) {
> x = 10;
> } else if (r == BB) {
> x = 11;
> } else if (r == CC) {
> x = 12;
> } else if (r == DD) {
> x = 13;
> } else if (r == EE) {
> x = 14;
> } else if (r == FF) {
> x = 15;
> } else if (r == GG) {
> x = 16;
> } else if (r == HH) {
> x = 17;
> } else if (r == II) {
> x = 18;
> } else if (r == JJ) {
> x = 19;
> } else {
> }
> }
> long t2 = System.currentTimeMillis();
> System.out.println("time for int[" + count + "] (ms): " + (t2 - t1));
> }
>
> private static void testEnum(int count) {
> int x = 0;
> Type[] ts = genRandomTypes(count);
>
> long t1 = System.currentTimeMillis();
> for (Type t : ts) {
> switch(t) {
> case A:
> x = 10;
> break;
> case B:
> x = 11;
> break;
> case C:
> x = 12;
> break;
> case D:
> x = 13;
> break;
> case E:
> x = 14;
> break;
> case F:
> x = 15;
> break;
> case G:
> x = 16;
> break;
> case H:
> x = 17;
> break;
> case I:
> x = 18;
> break;
> case J:
> x = 19;
> break;
> default:
> break;
> }
> }
> long t2 = System.currentTimeMillis();
> System.out.println("time for type[" + count + "] (ms): " + (t2 - t1));
> }
>
> public static void main(String args[]) {
> int[] cs = new int[] { 10, 100, 1000, 10000, 100000, 1000000, 10000000 };
> for (int c : cs) {
> testInt(c);
> testEnum(c);
> }
> }
> }
>
>
> ______________________________________________________________________
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: dev-help_at_grizzly.dev.java.net