#Why not use Object#clone? how is it bad? is ArrayType#clone also unsafe?
1 messages · Page 1 of 1 (latest)
<@&987246399047479336> please have a look, thanks.
Cloneable is problematic. You must implement clone on your type. The default behaviour is then to shallowly and blindly copy the values of all member fields - unless a superclass decides to override clone() to get some measure of deep cloning, in which case there's no established model for sub-class cloning (but the clone-method won't know that). And the cloning bypasses constructors. So it's easy to introduce bugs by breaking model invariants.
For arrays, clone is well-defined so generally this is considered fine.
On top of what Talden said
clone needs Cloneable interface, yet it is a marker interface, for whatever reason, and clone is a method that any object has, this is a terrible design, because it means you can't know at compile time if an object is cloneable, you also can't clone a generic object or an object where you have its interface because of this
on top of that, clone is quite literaly black magic, the way it works is alien to java, magically creating an object and init its fields without calling its constructor, by just calling super.clone(), this shouldn't make any sense in java, but that's how it works
and now the better alternative: a copy constructor
Array clone method still makes sense for performance reasons, although I prefer to use other methods
Not really
so I recommend avoiding the clone method, although you can still use it if you want, but don't implement it in your classes
No?
clone for arrays might not be faster
is the clone method in array not native?
it is native yes
but so are the other copy methods
Yea true
native also doesn't automatically mean faster. The JIT is so good that it can usually match or exceed native code for many things.
There is also the problem that java can't optimize native which means that a lot of native calls is slower
I agree, but some methods are not native for no reason
You mean inside method or invoke can be slower?
It means the JIT can't/won't attempt to rejigger it. It's a black box.
One of the optimisations is to perform escape analysis after inlining. The intrinsic for clone observes the identity so I suspect that in places where you use clone, the clone source is no longer a candidate for scalarisation. Now scalarisation doesn't happen nearly as much as we'd hope but it is possible that cloning could prevent an optimisation. I don't recall seeing any array scalarisation but since there is optimisation to constify bounds (observe that a particular array is always size N) I imagine this optimisation limitation could also apply to array cloning (less likely IMO however).
JIT is serious black-magic.
I recall the array clone performance issue revolves around it being able to skip the zero-ing out phase since it will be overwriting those locations immediately. I saw (within 6mos) someone had done benchmarks recently on which is faster for copying arrays and I think the consensus was just use Arrays.copy.