0

I'm trying to get better performance of object's serialization by usage of kryo library.

I have the next class

public class CustomClass {

  private String name;
  private int[] array;


  public CustomClass(String name, int size){
      this.name = name;
      fillArray(size);
  }

  private CustomClass(){ }

  private void fillArray(int size){
      array = new int[size];
      Random random = new Random();
      for (int i = 0; i < size; i++){
          array[i] = random.nextInt();
      }
  }
}

I'm serilizing it by this method, note I'm making serialization of single instance

public void kryoWrite(Object object){
    Kryo kryo = new Kryo();
    Output output = null;
    try {
        output = new Output(new FileOutputStream("kryo.txt"));
        kryo.writeObject(output, object);
    } catch (IOException e){
        e.printStackTrace();
    } finally {
        if (output != null) {
            output.close();
        }
    }
}

but serializing the same object using standard Java's Serializable interface works faster. For example, when I pass 1000000 as second param to constructor kryo serialize object in 188 ms, when Serializable serializes exactly the same object in 136 ms.

So what I'm doing wrong (is it a dubstep in my song, lol)?

EDIT

Serialization of array with size of 1000000, created and serializaed by these methods appropriately

public static int[] getArray(int size){
    int[] array = new int[size];
    Random random = new Random();
    for (int i = 0; i < size; i++){
        array[i] = random.nextInt();
    }
    return array;
}

public static void kryoWriteArray(int[] array) throws FileNotFoundException   {
    Kryo kryo = new Kryo();
    Output output = new Output(new FileOutputStream("array.txt"));
    output.writeInts(array);
    output.close();
}

takes 139 ms.

Mike Herasimov
  • 1,319
  • 3
  • 14
  • 31
  • Have you tried reusing the `Kryo` instance instead of creating a new one each time? Have you tried telling Kryo to write the entire array instead of each object? – Darth Android Apr 13 '16 at 16:13
  • @DarthAndroid I'm serializing one instance of CustomClass, I tried to write int[] array by kryo, but, again, perfomance is low – Mike Herasimov Apr 13 '16 at 16:16
  • @DarthAndroid this instance contains String and array of ints with size of 1000000 – Mike Herasimov Apr 13 '16 at 16:18

1 Answers1

1

At first it's hard to comment a benchmark if not the whole benchmark code is available. Please share it if further analysis is needed. Still, I'd already advice to pull object creation (new CustomObject) out of the benchmark if that's not already the case (and in general I'd create data of CustomObject outside and pass it into the class).

To be able to reproduce this issue I adopted Kryo's SerializationBenchmarkTest to test your CustomClass with an int[] of length 1000000 (please note that this benchmark measures serialization and deserialization combined, this could also be measured separately).

The consolidated result shows the following (check the mentioned commit for more details) for the best java serialization runs:

>>> Java serialization via Externalizable (best time): 870 ms
>>> Java serialization without try-catch via Externalizable (best time): 864 ms

For the best kryo serialization runs it shows:

>>> Kryo serialization without try-catch (best time): 835 ms
>>> Kryo unsafe serialization without try-catch, without ASM, without references (best time): 181 ms
>>> Kryo serialization without try-catch with fast streams (best time): 982 ms
>>> Kryo unmodified serialization (best time): 1,108 ms
>>> Kryo unsafe serialization without try-catch, without ASM (best time): 191 ms
>>> Kryo unsafe serialization without try-catch (best time): 193 ms
>>> Kryo serialization (best time): 989 ms

As it seems, Unsafe based serialization seems to do the trick here, so I'd say you should try Kryo's UnsafeOutput instead of Output.

MartinGrotzke
  • 1,301
  • 8
  • 13