6 ms·
Java IAQ
- lucian1900 15y agoA little outdated, the one about HashMaps and equals is moot with generics. Still quite interesting.
- swah 15y agoIts not like Java is changing that much :) Is this still true these days: "creating a new object is a fairly expensive operation" ?
- qznc 15y agoShort answer: not necessarily A good JVM contains optimizations, which makes it cheap. For example, it will try to allocate the object on the stack instead of the heap. Apart from field initialization, this costs nothing, because the stack pointer probably had to be changed anyways.
- oconnor0 15y agoCreating a new object is never free, but it used to be far more expensive. To my knowledge the original Java GCs weren't compacting & had to find the best place in the heap to stick a new object. This required a linear search of the available free blocks. This is obviously much slower than incrementing a pointer at the edge of your used space. Unfortunately my search-fu has failed me & I can't find corroboration of my claim. My impression of Java these days is to start with the "right" thing (allocate as needed, etc) and not to overly concern yourself with performance until it becomes an issue. There are certainly situations where allocating lots of objects (say billions or, maybe, millions) causes performance issues, but creating object pools to preemptively avoid that is a lot of extra work that may not be worth it.
- codeflo 15y agoIt's not. HashMap<K, V> works exactly like Hashtable with regards to equals() and hashCode().
- lucian1900 15y agoAh, interesting.
- deleted 15y ago[deleted]
- smackfu 15y agoIf you are interested in this kind of stuff, Effective Java is a must-read book. Long, good explanations of how to do stuff right. Also, the 2nd edition covers up through Java 1.6.
- stiff 15y agoI second this recommendation, actually even if you do not program in Java nor on the JVM. Like no other book it taught me a particular kind of foresight - to analyse the consequences of each small decision being made during implementing some new thing and to design things in such a way that they are least likely to cause problems now or in the future, to me or to other programmers working on the project - my code is much more solid and less error-prone ever since and it was definitely a big AHA moment for me. The author, Joshua Bloch, designed some of the standard Java APIs and I actually can't think of a better way to learn about those things than implementing an API used by other people, which explains why he has so many interesting things to say that are seldom found in other places. Here is also a very nice talk by the author: http://www.infoq.com/presentations/effective-api-design http://www.infoq.com/presentations/effective-api-design
- peeters 15y agoThis appears to have been written before IDEs were invented. The author suggests that it's acceptable to extend a class just to gain unqualified access to its static methods to save a few characters of typing.
- tptacek 15y agoDid you read "Scheme In One Class" at the link he attached to the paragraph you're sniping at?
- peeters 15y agoYes I have, and in that he reiterates that it's just to achieve unqualified access (i.e. save a few keystrokes, which is not an issue with any moderately good IDE): > I came up with the idea of putting the utility methods in their own class, SchemeUtils, and then having the five other top-level classes extend SchemeUtils. That way, I can use the unqualified name, and I get the modularity I want. It's not a huge deal in his project since he obviously wasn't using OOP anyhow, but it really is an abuse of inheritance with no benefit.
- Drbble 15y agoWhat IDE will hide the qualifying class names of method calls? I was searching for that yesterday, but the best I could so is syntax highlighting to make classes display in a very faint color, but Eclipse can't distinguish type declarations from method qualifiers from class declarations, nor will it fold away the class names I want to hide, so it's not ideal. Coding is 10% reading and 90% reading, so an IDE that only helps with writing code is approximately worthless.
- deleted 15y ago[deleted]
- krrose27 15y agoGoes directly to "What other operations are surprisingly slow?" and attempts to write micro benchmark with the same results. Fails.... Most of the general stuff is accurate and dandy but I don't believe you should listen to many (most likely any) of the speed related statements as this article appears to have been written in 1998. Topic should be "Java IAQ circa 1998".
- typicalrunt 15y agoBut note the warning from Sun: "So when should you use static import? Very sparingly!" I'm so glad there is an authoritative answer on this subject. IMHO, I hate the use of static imports because it becomes difficult to know where a particular method comes from... where it's an instance method from the class itself or one that is brought in through a static import. And then there's the possibility of clobbering the namespace by including a local variable name and a statically imported variable.
- peeters 15y agoI don't like them in general either, but there's one place I use them extensively: JUnit tests (statically import Mockito, Hamcrest, Assert, etc). It mostly has to do with how much the library tries to be a DSL, and how much readability will suffer if I don't use a static import. IMO, this assertThat(6, isGreaterThan(5)); reads a heckuva lot better than Assert.assertThat(6, Matchers.isGreaterThan(5)); Of course the combination of poor Java type inference and Generics-heavy libraries make it so that often I have to do the latter to make use of angle braces, but that's another story.
- ZitchDog 15y agoIt really should be Assert.that(6, Is.greaterThan(7)), shouldn't it? Best of both worlds!
- Drbble 15y agoI don't understand this comment at all. Do you not know that import statements are at the top of every class file, or did you mean that you hate wildcard imports? Do you also eschew local variables, because they might clobber fields and method parameters if you ignore the compiler warnings?
- typicalrunt 15y agoJava compilers are very poor at lifting constant expressions out of loops. The C/Java for loop is a bad abstraction, because it encourages re-computation of the end value in the most typical case. So for(int i=0; i<str.length(); i++) is three times slower than int len = str.length(); for(int i=0; i<len; i++) Does anyone know if this is still valid advice? I recall reading somewhere that the JIT has optimized around this problem.
- krrose27 15y agoThe thing is String.length() doesn't do any re-computation. All it does is return a variable defined in the String object that is modified when the string it contains changes. See my other comment saying you should ignore any speed suggestions by the article.
- kodablah 15y agoThat is correct from the String source I am seeing. It simply returns a field, so the JVM probably inlines it into the for loop conditional making this advice not really necessary.
- smackfu 15y agoI like this way to rewrite it when the end test is slow (I think this is correct syntax): for(int i=0, len=str.length(); i<len; i++) One evaluation and you don't have an extra len variable hanging around.
- Someone 15y agoFor this example, I would expect that any decent Java compiler optimizes this away nowadays. That does introduce a dependency between compiler and standard library, but the benefit is large enough, given that this is idiomatic code, and that Java has it easy here because Java strings are immutable. For general collections, things are more difficult, but I still expect java to optimize things in many cases. I haven't checked, though. A C/C++ compiler has a tougher job. It can only move strlen calls out of a loop if it can determine that the strlen you call came from the correct <header> file and that there is no defined behavior under which either the pointer or its contents change inside the loop. If it cannot do either, it must 'call' strlen each time through the loop (That 'call' can be inlined, especially if the compiler knows it is the standard library's strlen)
- js2 15y agoFWIW, last changed July 13, 1998 according to the source.
- nailer 15y agoI have an IAQ of my own: Why is it that Java VMs seem to have such different interactive latency when compared to other memory-managed language VMs? Is the performance of eg, eclipse or Android or the Java browser plugin something to with the GC kicking in too aggressively? Over the last decade I've heard different explanations re: SWT/swing/AWT toolkits, and server-side optimizations being default in desktop VMs, but I'm fairly sure both issues should be resolved now. Nevertheless, my general experience seems to be if it's Java based, it seems to handle touch/mouse events noticeably worse than otherwise. Maybe .net and Python and the rest are doing more of their UI work in C?
- mbell 15y agoThis has a lot more to do with the GUI toolkits than the JVM. Python is most often used with bindings for GTK (C), QT (C++) or tk (C). I don't know a lot about .net but I believe it just links to the standard windows gui toolkit probably also written in native code. For Java the main issue is that Swing/SWT/AWT suck and java is mostly used as a server language so there is little impetus to fix them. Eclipse is just bloated, that is why its often slow. Android has its own custom JVM (Dalvik) but I imagine the majority of the UI rendering / handling code is native with Java bindings. All that said, the full JVM (both openJDK and sun's) have multiple garbage collectors and many tuning options. This creates flexibility to tune the GC for particular work loads but also makes them complicated to work with. It doesn't help that the default GC/memory settings in the JVM are a bit...off, and use the high throughput GC vs the low pause collectors.
- nvarsj 15y agoIt's pretty simple... Hotspot collectors are optimized for throughput, not latency. That's where the money is for Sun/Oracle. It's a trade off between one and the other in any garbage collector. You can tune it to some extent.
- lars 15y agoIt's been a while since I've done work in Java, but I'm pretty sure the GC is not to blame for this. Java uses a concurrent mark and sweep GC. The concurrent part means it does not pause the world while it's collecting. So as mbell says, it has to do with the UI frameworks. But I don't think it has to do with whether or not the UI code is written in C either. In the UI frameworks I've used for both Python and Ruby, you could write slow interpreted code that would run on the UI thread. The key thing was you tended not to do it, because the frameworks didn't encourage you to do so. The problem is that Java frameworks make it easy to for example do IO on the UI thread, whereas the other frameworks make it hard. Threading is relatively hard to get right in any of these languages, so the choices made by the framework authors really matter. Another thing contributing to Java being perceived as being slow is the long boot time of the JVM. (It used to be slow at least, don't know if it still is.)
- KonradKlause 15y agoThe page links also to a C IAQ: http://www.seebs.net/faqs/c-iaq.html http://www.seebs.net/faqs/c-iaq.html I've never seen that many wrong C statements. :-)