0

Since System.arraycopy() and clone() does only shallow copying, I wonder if this approach would work for doing a deep copy.

ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
ObjectOutputStream oos = new ObjectOutputStream(bos);
long x=System.nanoTime();
oos.writeObject(fromArray);
oos.flush();
ByteArrayInputStream bin = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream  ois = new ObjectInputStream(bin);
Object o=ois.readObject();          
double timeTaken= (System.nanoTime()-x)/1000000000.0;

1) Will the variable, timeTaken give me the actual time to do a deep copy?

2) If I pass data say an array of size 1MB like

byte[] fromArray = new byte[1024*1024];

and calculate throughput in Mb/sec like,

double throughput=1/timeTaken;

Will it be reasonable to consider this as a memory benchmarking throughput?

Prasanna
  • 2,593
  • 7
  • 39
  • 53
  • 1
    An interesting take at deep copying. This technique would be subject to all the limitations of serialization, of course. Have you taken a look at frameworks like [Dozer](http://dozer.sourceforge.net/)? – Perception Jan 30 '13 at 05:49
  • 2
    What exactly are you trying to benchmark? How quickly the JVM can traverse an object graph, or how quickly it can read from a contiguous block of memory? The two *could* be very different. – SimonC Jan 30 '13 at 06:20
  • I am trying to benchmark how quickly I can read and write a chunk of data(1B, 1Kb,and 1Mb) to memory. – Prasanna Jan 30 '13 at 06:24
  • do you hope for some magical memcopy behind the serialization? why don't you just read/write the memory arr[i]=j;arr[i]==j;? – cybye Jan 30 '13 at 06:32
  • @Prasanna: the amount of time it takes to read and write RAM will be completely dominated by caching effects and locality of reference, so your benchmark is unlikely to give you meaningful results. You are obviously concerned that something is or will be too slow. If you explained your use case, you would be much more likely to get helpful answers. – Daniel Pryden Jan 30 '13 at 06:51

2 Answers2

2

I wonder if this approach would work for doing a deep copy.

It will work1. It is not the most efficient way to implement deep copying though. (Implementing deep copy by hand is probably an order of magnitude faster.)

Will the variable, timeTaken give me the actual time to do a deep copy?

It depends. If the JVM has been suitably warmed up, then this should give an accurate measure. But it is a measure of this way of doing deep copy ... not deep copy in the general sense. (And see above ...)

Will it be reasonable to consider this as a memory benchmarking throughput?

No. The work involved in object serialization and deserialization is far to heterogeneous to be considered a valid proxy for memory system performance.

As a comment suggested, you would be better off bulk copying data from one array to another using System.arraycopy. Better yet, do your benchmarking in a language that is "closer to the metal"; e.g. in C or assembly language.


1 - I'm assuming that the object graph you are copying is fully serializable.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Deep cloning via serialization does not work in all cases. Particularly when member classes of the object graph are not serializable (or only partially so, due to transient fields). The technique is also vulnerable to bad implementations of `writeObject`, `readObject`, aka custom serialization. – Perception Jan 30 '13 at 07:58
1

The simple answer is: No, this is not the right approach. Without knowing what you're trying to accomplish, it's hard to know what the right approach should be, but if you really want to write a micro-benchmark for copying memory(!) then you must first read this: How do I write a correct micro-benchmark in Java?

Community
  • 1
  • 1
Daniel Pryden
  • 59,486
  • 16
  • 97
  • 135