Bug #5706 | getString on a varchar(64) field cause ClassCastException in debuggers | ||
---|---|---|---|
Submitted: | 22 Sep 2004 18:47 | Modified: | 24 Sep 2004 14:38 |
Reporter: | Quartz 12h | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | Connector / J | Severity: | S3 (Non-critical) |
Version: | 3.1.4beta | OS: | Windows (win xp) |
Assigned to: | Mark Matthews | CPU Architecture: | Any |
[22 Sep 2004 18:47]
Quartz 12h
[23 Sep 2004 7:59]
Mark Matthews
Unfortunately, benchmarking shows that switching to instanceof, even on modern JVMs (1.4/1.5) is approximately 20% slower for this use case in a very 'hot' portion of code for most users.
[24 Sep 2004 14:17]
Quartz 12h
Those benchmarks are certainly not hitting the case where the classcast exception will be created and thrown. Here is a clean proof of this cost. Not only casting is not expensive at all, it beraly show even with a million invocation (code below uses 100'000 only, because it would be too long with exception!) Second observation, if the stacktrace is deep, it is even slower. Creating an exception is trashing menory anyway. Bad pratice. Thanks for considering the suggested code fix. public class TestExceptionCost { public static void main(String[] args) { System.out.println("----------Small stack--------------"); test(0); System.out.println("----------Big stack--------------"); test(100); } static final int LOOP = 100000; static void test(int n) { if(n>=0) { test(n-1); } else { long t, d; int good, bad; Object obj; //relax jvm time: try {Thread.sleep(1000); } catch(InterruptedException e){} //----------test positive cases------------- obj = "toto"; good = bad = 0; t = System.currentTimeMillis(); for(int i=0; i<LOOP; i++) { try { String s = (String)obj; good++; } catch(ClassCastException e) { bad++; } } d = System.currentTimeMillis() - t; System.out.println("by exception, no bad cast : "+d+" ms, good="+good+", bad="+bad); //----------test negative cases------------- obj = new byte[4]; good = bad = 0; t = System.currentTimeMillis(); for(int i=0; i<LOOP; i++) { try { String s = (String)obj; good++; } catch(ClassCastException e) { bad++; } } d = System.currentTimeMillis() - t; System.out.println("by exception, bad cast : "+d+" ms, good="+good+", bad="+bad); //----------test positive cases------------- obj = "toto"; good = bad = 0; t = System.currentTimeMillis(); for(int i=0; i<LOOP; i++) { if(obj instanceof String) { String s = (String)obj; good++; } else { bad++; } } d = System.currentTimeMillis() - t; System.out.println("by instanceof, with cast : "+d+" ms, good="+good+", bad="+bad); //----------test negative cases------------- obj = new byte[4]; good = bad = 0; t = System.currentTimeMillis(); for(int i=0; i<LOOP; i++) { if(obj instanceof String) { String s = (String)obj; good++; } else { bad++; } } d = System.currentTimeMillis() - t; System.out.println("by instanceof, without cast: "+d+" ms, good="+good+", bad="+bad); } } }
[24 Sep 2004 14:38]
Mark Matthews
The benchmark did cause the class-cast exceptions to be thrown, however it didn't show the same results as yours. The point about trashing memory is taken, so we've fixed it to use instanceof. This will be in tonight's nightly snapshot build.