4

I use simple Jackson code to convert from my object to json String, but it really slow. It takes 70 milisecond to convert only one object as below in my machine. Did I do something wong?

ObjectMapper myObjectMapper = new ObjectMapper();
void testJson()
{

    MyClass state = new MyClass();
    try
    {
        String result = myObjectMapper.writeValueAsString(state);
    } catch (Exception ex)
    {

    }

}

MyClass with only 4 members

 MyClass
    {
    public int a;
        public  int b;
        public int c;
        public String d;
    }
daddylonglegs
  • 75
  • 1
  • 1
  • 8
  • 6
    You cannot just measure performance from _one_ creation... Try and run it 1000 times and you will see that it takes far less than 70 ms * 1000. – fge Mar 24 '14 at 09:27
  • I agree, but comparing to built-in serialization of java. I've tested 10000 times and serialization has won.(I've changed Jackson to writeValueAsBytes). My main purpose is to convert from object to byte[]. Thanks – daddylonglegs Mar 24 '14 at 09:44
  • 2
    Builtin serialization and Jackson don't have the same purpose at all! You are comparing apples and oranges here. If you want to use Jackson, it means you have a use for JSON; builtin serialization cannot do that for you. – fge Mar 24 '14 at 09:46
  • Yeah, do you know some other ways to convert from object to byte array?. That's what i'm doing. – daddylonglegs Mar 24 '14 at 09:49
  • Your question is vague; what do you want to do with this byte array? Send it to a peer? Use it locally only? – fge Mar 24 '14 at 09:55
  • How about not treating the byte array as an object but just as it is - an array of bytes? Basic IO allows you to read and write them. – Gimby Mar 24 '14 at 09:56
  • I convert object to byte array to send it over TCP network. And the I need both high speed and low size – daddylonglegs Mar 24 '14 at 09:58
  • @Gimby I don't understand your aprroach. I need to convert MyClass's instance into byte array, then send it over network – daddylonglegs Mar 24 '14 at 10:03
  • Oh sorry, I was being confused by you saying "do you know some other ways to convert from object to byte array?". You made it sound like you were trying to serialize a byte array, not an object of your own custom class. – Gimby Mar 24 '14 at 10:05
  • Now I found out three solutions for sending MyClass's instance over network: 1: use Jackson to convert into byte[] and send. 2: use built-in serialization to convert into byte[] and send. 3: convert MyClass's members into String, then into byte[] and send. Is there any other better solution ?. Thank to all you – daddylonglegs Mar 24 '14 at 10:08
  • are you reusing the ObjectMapper instance? Its my understanding it does some sort of internal caching. You could try reusing the ObjectMapper and see if you see any gains. – DangerDan Mar 24 '14 at 18:21

1 Answers1

10

I use simple Jackson code to convert from my object to json String, but it really slow. It takes 70 milisecond to convert only one object as below in my machine. Did I do something wrong?

70 milliseconds to encode and send a little JSON message is implausible. There is little doubt in my mind that the real explanation is that the 70 millisecond measurement an artifact of the way that you benchmarked your code. Probably, you didn't allow for JVM warm-up effects.

So, yes, you did your benchmarking incorrectly. Probably. For more information on what you may have done wrong, see:


Now I found out three solutions for sending MyClass's instance over network: 1: use Jackson to convert into byte[] and send. 2: use built-in serialization to convert into byte[] and send. 3: convert MyClass's members into String, then into byte[] and send. Is there any other better solution ?

In theory (i.e. if you have enough skill, time and patience) the best performance can be achieved by encoding the data by hand into a byte buffer and sending that. But that is only theoretical.

If you are looking for practical solutions that are potentially faster than the alternatives you have tried, take a look at Google Protocol Buffers. They are reputed to be fast ...

But I suspect that you may have drawn the wrong conclusion from your (probably) poorly designed benchmark; see above. I strongly recommend you redo that before you look for faster alternatives.


70 milliseconds for one object, but when I try 1000 objects, it only takes 114 milliseconds, isn't it strange?

Actually, it is not at all strange when you take account of the way that the JVM works.

When the JVM starts, it loads your code and starts running it using the bytecode interpreter. After the code has been interpreted for a bit, the JVM runs the JIT compiler to produce optimized native code for the methods that are being called frequently. This compilation process takes a significant amount of time.

So when you are measuring the time taken to send one object, you are probably really measuring the time to send one object AND do a bunch of JIT compilation. But that JIT compilation work won't need to repeated. Net result - processing one object appears to takes a surprising long time, compared to 1000.

JIT compilation is one of the common JVM warmup effects that can distort a poorly written Java benchmark.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 70 miliseconds for one object, but when I try 1000 objects, it only takes 114 miliseconds, isn't it strange?. I willtake a look at Google Protocol... later. MyClass is quite simple, it just contains some members that stores data to transfer. So I just build a String such as: "1,100,abc", then encode it into bytes, and implement method to decode. – daddylonglegs Mar 24 '14 at 10:55
  • *"Isn't it strange?"* - Nope. It is just consistent with a poorly designed benchmark. – Stephen C Mar 20 '22 at 04:29