-1

I am running the following code comparing different json deserialization libraries. Thats not the point, point is when i run this code, the first deserialization takes huge time compared to subsequent (which are more or less equal). Please advise what can be the reason for the same. The reason i am asking is that in my REST API method, I always get the "first" time, and it never improves.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import com.dslplatform.json.DslJson;
import com.dslplatform.json.runtime.Settings;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.blackbird.BlackbirdModule;
import com.test.response.ResponseObj;

public class TestMainClass {
    private static DslJson<ResponseObj> dslJson = new DslJson<>(Settings.basicSetup());
    private static ObjectMapper mapper = new ObjectMapper().registerModule(new BlackbirdModule());

    public static void main(String[] args) {

        for (int i = 1; i <= 6; i++) {
            long time1 = 0;
            try (InputStream inputStream = new FileInputStream(new File("/home/user/dir/test" + i + ".json"))) {
                time1 = System.currentTimeMillis();
                ResponseObj object = dslJson.deserialize(ResponseObj.class, inputStream);
            } catch (Exception e) {
                e.printStackTrace();
            }
            long time2 = System.currentTimeMillis();
            long time3 = 0;
            try (InputStream inputStream = new FileInputStream(new File("/home/user/dir/test" + i + ".json"))) {
                time3 = System.currentTimeMillis();
                ResponseObj object = mapper.readValue(inputStream, ResponseObj.class);
            } catch (Exception e) {
                e.printStackTrace();
            }
            long time4 = System.currentTimeMillis();
            System.out.println("Time DSL:" + (time2 - time1) + ", BB:" + (time4 - time3));
        }

    }

}

Each test file is same and of 3 MB approximately.
Following is one of the output:
Time DSL:158, BB:539
Time DSL:44, BB:110
Time DSL:31, BB:75
Time DSL:26, BB:39
Time DSL:18, BB:37
Time DSL:16, BB:29

Edit 1: I tried storing data in string (bytes) at once and then parsing the same. I get the same result. Only entering the changes i made, rest remains same.
public static void main(String[] args) {

        byte[] bytes = null;
        try (InputStream inputStream = new FileInputStream(new File("/home/user/dir/test1.json"))) {
            bytes = inputStream.readAllBytes();
        } catch (Exception e) {
            e.printStackTrace();
        }

        for (int i = 1; i <= 6; i++) {
            long time1 = System.currentTimeMillis();
            try {
                ResponseObj object = dslJson.deserialize(ResponseObj.class, bytes, bytes.length);
            } catch (Exception e) {
                e.printStackTrace();
            }
            long time2 = System.currentTimeMillis();
            long time3 = System.currentTimeMillis();
            try {
                ResponseObj object = mapper.readValue(new String(bytes), ResponseObj.class);
            } catch (Exception e) {
                e.printStackTrace();
            }
            long time4 = System.currentTimeMillis();
            System.out.println("Time DSL:" + (time2 - time1) + ", BB:" + (time4 - time3));
        }

    }

Below are the results:
Time DSL:174, BB:674
Time DSL:65, BB:105
Time DSL:44, BB:91
Time DSL:41, BB:105
Time DSL:42, BB:96
Time DSL:29, BB:71
  • Your benchmarks are flawed: You'll primarily be benchmarking I/O (which can vary vastly f.ex. due to caching effects) there. To avoid this, consider reading the entire file into memory first, then using a `StringReader`. – Luatic Aug 11 '23 at 14:34
  • @Luatic I have tried with String but still same results. – Yash Londhe Aug 11 '23 at 15:01
  • Well, this is still a microbenchmarking, spanning only a few milliseconds. You should run both parsers more often (say, a thousand times), and average it out such that various noise doesn't skew the results too much. Also try to keep noise low, e.g. by assigning a processor core to just this task. – Luatic Aug 11 '23 at 15:08
  • You should do `mapper.readValue(bytes, ResponseObj.class)` to compare apples with apples – lance-java Aug 11 '23 at 15:45
  • You should also run a few hundred (or thousand) times before starting the timers to warm up the jvm. Then take the average over thousands of executions... not 6 – lance-java Aug 11 '23 at 15:48

0 Answers0