5 ms·
Groovy Array: it just keeps going...and going...
- jff 16y agoI just went to post that... can anybody explain to me what exactly is going on? I'm not familiar with Groovy, and I try to forget Java when I can, but this just plain doesn't make any sense.
- akronim 16y agoThey're aiming for compatibility with Java 1.4, which doesn't have varargs. In java 1.5 you could just write public static Object[] createArray(Object... args) { return args; }
- abp 16y agoSo just another missing line of essential commentary?
- zmmmmm 16y agoI remember discovering this and deciding to eliminate it as part of an effort to compress the groovy jar file a bit more (long story, but basically I was running some Groovy in an applet, every byte counts). I thought I'd found a jackpot and that killing this class would surely eliminate a nice chunk of byte code. To my amazement it makes almost no difference. With pack200 the redundancy of all these methods is totally stripped out. It took me an hour or so of work and I think it made less than 200 bytes difference in the end.
- riffraff 16y agowell, java has variable length arguments now so the whole file could be simply public static Object[] createArray() { return EMPTY; } public static Object[] createArray(Object... args) { return args; } My guess is they probably had this before java supported such a syntax so that you could create arrays easily. once you auto-generate the file, you just do it up to 255. I do not have a good explanation of why this is better than the normal array initializer though, apart from the fact that once you standardize on this you may have some minimal advantage in not allocating empty arrays around.
- lepht 16y ago>My guess is they probably had this before java supported such a syntax so that you could create arrays easily varargs came in Java 1.5, September 30, 2004 Groovy 1.0, January 2, 2007 Definitely could be for compiler optimizations or backwards compatibility, just providing some context for any possible historical reasons like the one you stated.
- bruceboughton 16y agoIf it's for optimisation, why introduce another method call (ArrayUtil.createArray) instead of using new Object[] { .. } directly? I can understand the backwards compatibility argument, but I just don't see the need for this ArrayUtil class.
- lepht 16y agoTwo things: Calling new Object[]{} directly is going to call the constructor for Object anyway, so there's no really difference in the number of method calls for either. Also, in terms of optimization: calling new Object[]{...} makes it so that the size of the array isn't known until runtime when the initialization parameters can be evaluated. Because array length is immutable the JVM must wait until execution to create an array of the proper size. With the overloaded static createArray() methods used in ArrayUtils the size of the array can be determined and memory allocated (based on the number of parameters at the callsite and hence which variation of the method should be called) at the JRE's convenience/when optimal. All of this is probably micro-optimization to the who-really-cares level, and might even be irrelevant due to javac/JIT magic, just wanted to show that the existence of the new Object[] syntax doesn't preclude there being performance gains from using something like ArrayUtil.createArray().
- GrandMasterBirt 16y agoCompatibility :) In any case, you can easily generate an ant script or whatever build groovy uses to either generate the vararg code or the insaneo source code as we see here. The point being that this should only happen when compiling groovy for java 1.4.
- nysauhem 16y agoYou could accomplish the same thing with a public static Object[] createArray(Object... objects) { ... } but doing it statically, hard-coded like this is faster. You leave it to the compiler to determine the length of the arguments, rather than having to count them at run-time. The Google Guava library does something similar, but not to this extent, only up to 12 args http://guava-libraries.googlecode.com/svn-history/r12/trunk/javadoc/com/google/common/collect/ImmutableList.html http://guava-libraries.googlecode.com/svn-history/r12/trunk/...
- xiongchiamiov 16y agoCan't you use variadic function parameters? public static Object[] createArray(Object... args) { return args; } I haven't done any Java in a while, so I'm just piecing this together from StackOverflow examples (with compiling, of course).
- Psyonic 16y agoSince Java 1.5, yes. Perhaps it's an issue of backwards compatibility.
- xiongchiamiov 16y ago*without compiling
- 9ec4c12949a4f3 16y agoFile that lists functions with with excessive arguments? <insert meme face> Front page material!!!
- deleted 16y ago[deleted]
- briancarper 16y agoThere are some similar horrors in the source code for Clojure. https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IFn.java https://github.com/clojure/clojure/blob/master/src/jvm/cloju... Java is a harsh mistress. This is why dynamic languages on the JVM are nice, so I never have to write code like this myself.
- Psyonic 16y agoI can't be sure, but in the Clojure case it appears to be done for performance reasons. The final definition of invoke uses varargs for everything after 20, so it's not an issue of compatibility.
- jcromartie 16y agoAs long as nobody is maintaining that type of code by hand, I don't care what makes the JVM happy.
- powertower 16y agoThis is a good example of how projects turn out that are outsourced and get billed by a lines-of-code metric. (just as an example ... I'm aware that this is not the case here)
- wlievens 16y agoIf it's not a case here, how could this be a good example? This is an example of generating code to work around a limitation. You can approve or disapprove of the whole situation, but it does have technical merit.
- emehrkay 16y agoI need to instantiate an array with 251 members. Guess I'm out of luck
- Groxx 16y agoI'm curious: Why don't people just use `new Object[]{arg1, arg2...}` ? It's one letter longer than `createArray(arg1, arg1...)`, doesn't require you to include that chunk of code, is infinite in length, and allows you to statically-type it in your type of choice. Heck, it's the same code, just removing a layer of indirection. edit: noticed it's one character longer, not the same length. Maybe that's why?
- chrisbroadfoot 16y agoThis isn't regular code. This is code for the groovy runtime.
- Groxx 16y agoSo, why don't the Groovy runtime programmers just write `new Object[]{arg1, arg2...}` ?
- tedunangst 16y agoI suspect this is code meant to be called by generated bytecode, and generating the bytecode to call said function is easier than generating the bytecode to make a new object[]?
- wlievens 16y agoIt's been a while since I generated JVM bytecode (oh my, five years), but I don't recall there being array initializer instructions. In other words, the new Object[] {...} statement probably translates to a whole bunch of array-write operations on the caller side whereas with a method call you just push them all on the stack and invoke the utility method.
- tomn 16y agoThis is what comments were made for! I'm sure it's legitimate, but you'd have to be insane to look at that code and not question why it exists.
- code_duck 16y agoOne could also say you'd have to be sophomoric to assume the person who put if there didn't do so for a good reason.
- tomn 16y agoAs I said, I'm sure that it's legitimate, but it's definitely not good code, and I'd rather not have it lurking in my codebase for years on end. If you don't know the original motivation behind writing something like that, you can't really remove it for fear of the original bug cropping up again without you noticing. (I guess, then this is also what test cases are for...)
- vorg 16y agoA coding comment could say why 250 was chosen, and not 256, or Scala's 22 for max tuple sizes.
- eneveu 16y agoFor the late-comers (like me!), Javadoc comments were added since the parent comment was posted: $ svn log -r {2010-11-30}:HEAD http://svn.codehaus.org/groovy/trunk/groovy/groovy-core/src/main/org/codehaus/groovy/runtime/ArrayUtil.java ------------------------------------------------------------------------ r21150 | hamletdrc | 2010-11-30 19:32:11 +0100 (Tue, 30 Nov 2010) | 3 lines updated javadoc on arrayutil ------------------------------------------------------------------------ r21152 | hamletdrc | 2010-11-30 21:31:24 +0100 (Tue, 30 Nov 2010) | 1 line Updated ArrayUtil javadoc one more time so that people quite wondering what it is used for.
- chrisbroadfoot 16y agoIt's probably generated. Here's a one-liner in Groovy to generate the class body: (0..249).each { println "public static Object[] createArray(${(0..it).collect{'Object arg'+it}.join(', ')}) {\n\treturn new Object[]{\n\t\t${(0..it).collect{'arg'+it}.join(', ')}};\n}\n" } Sorry it's not the most readable thing ;)
- deleted 16y ago[deleted]
- robinduckett 16y agoAnd this is why I like dynamic languages.
- bruceboughton 16y agoCare to explain?
- brazzy 16y agoGroovy is a dynamic language. This is what it has to do behind the curtains, and even then only for backwards compatibility. Your own favorite dynamic language is most likely doing worse things deep inside the runtime code where you can't see it.