I'm kind of curious what you're actually doing, then.
Building graph from series of line segments - "roads". Every intersection becomes node. Completely real-life task.
But in the vast majority of cases that I've actually worked on, the time spent either waiting for the user or on I/O dwarfed the time spent on the GC or on memory allocation
I absolutely agree, factually you are right. The problem is, in the real life code is usually being reused whenever possible. So you cannot really predict usage pattern for primitives like this beforehand.
Also, you are probably thinking about Java on PC, where JIT compiler is smart and memory is usually not deallocated at all (once after process ends). But there're many other Java devices out there. I knew some cellphones where memory allocation gets terribly slow once many objects are created. Just to be on the safe side, if you can write it right, why not do it from the very beginning?
Actually, I did some measurements. I'll not comment, but some things were completely surprising for myself. At least I agree profiling is important :)
iterations (more is better) |
constructor |
equals(Point other) implementation, x part |
hashCode() implementation |
hashCode(double value) implementation |
97 |
this.x = x; ... |
Double.valueOf(this.x).equals(other.x) |
hashCode(this.x) ^ hashCode(this.y) |
hashCode(Double.doubleToLongBits(this.x)) |
107 |
this.x = new Double(x); ... |
this.x.equals(other.x) |
this.x.hashCode() ^ this.y.hashCode() |
|
117 |
this.x = x; ... |
Double.doubleToLongBits(this.x) == ... |
hashCode(this.x) ^ hashCode(this.y) |
hashCode(Double.doubleToLongBits(this.x)) |
382 |
this.x = x; ... |
Double.doubleToRawLongBits(this.x) == ... |
hashCode(this.x) ^ hashCode(this.y) |
hashCode(Double.doubleToRawLongBits(this.x)) |
401 |
Point2D.Double |
536 |
...; this.hashCode = /* same as above */; |
Double.doubleToRawLongBits(this.x) == ... |
this.hashCode |
hashCode(Double.doubleToRawLongBits(this.x)) |
547 |
this.x = x + 0.0; ... |
Double.doubleToRawLongBits(this.x) == ... |
hashCode(this.x) ^ (hashCode(this.y) rol 16) |
hashCode(Double.doubleToRawLongBits(this.x)) |
573 |
this.x = x; ... |
Double.doubleToRawLongBits(this.x) == ... |
hashCode(this.x) ^ (hashCode(this.y) rol 16) |
hashCode(Double.doubleToRawLongBits(this.x)) |
How figures were obtained: 0x10000 objects with random coordinates from 16x16 grid were created and inserted into LinkedHashSet
of default size unless they were already there (i.e. mostly just checking). Then set was clear()
-ed and process repeated, number of repetitions in 10 seconds was counted.
P.S. Nazi forum does not allow me to define own stylesheets!