Попытка проверить производительность двух JSON-фреймворков - выглядит ли это правильно? - PullRequest
0 голосов
/ 17 февраля 2012

В моем приложении - я использую JSON для сериализации и до этого момента - я использовал GSON. Хорошо, это был довольно медленный, особенно начальный знак, когда я загружаю объекты.

Я изучил варианты и нашел Джексона. Я сделал быстрый тест с циклом и десериализацией 1000 образцов объектов. Джексон был как 3x-5x быстрее.

Теперь я создал оболочку, чтобы переключаться между библиотеками, и начал тестировать, глядя бок о бок на то, что я получаю от каждой библиотеки. Вот мой код:

public static <T> T fromJson(String json, Class<T> classOfT) throws Exception
    {
        T returnObject;

        Long milliseconds = (new Date()).getTime();
        returnObject = MyGsonWrapper.getMyGson().fromJson(json, classOfT);
        Long gsonTime = (new Date()).getTime() - milliseconds;

        milliseconds = (new Date()).getTime();
        returnObject = MyJacksonWrapper.getMyJson().readValue(json, classOfT);
        Long jacksonTime = (new Date()).getTime() - milliseconds;

if (gsonTime < jacksonTime)
        {
            Log.d(LOG_TAG, "------------- GSON Wins by " + Long.toString(jacksonTime - gsonTime) + " object: " + classOfT.getName());
        }
        else
        {
            Log.d(LOG_TAG, "------------- Jackson Wins by " + Long.toString(gsonTime - jacksonTime) + " object: " + classOfT.getName());
        }

Есть ли в моем коде информация о том, как я получаю измерения времени? Суть в том, что отличия незначительны, и GSON доказал свою работоспособность, поэтому я не знаю ... Реальная жизнь отличалась от моей первоначальной оценки. И с Джексоном он тоже не чувствует быстрее ..

02-17 10:23:26.068: DEBUG/com.idatt.json.JsonWrapper(12004): ------------- GSON Wins by 108 object: [Lcom.idatt.json.UserPreference;
02-17 10:23:28.006: DEBUG/com.idatt.json.JsonWrapper(12004): ------------- Jackson Wins by 34 object: [Lcom.idatt.json.MailTemplate;
02-17 10:23:29.154: DEBUG/com.idatt.json.JsonWrapper(12004): ------------- GSON Wins by 27 object: [Lcom.idatt.json.MailItem;
02-17 10:23:36.514: DEBUG/com.idatt.json.JsonWrapper(12004): ------------- Jackson Wins by 599 object: [Lcom.idatt.json.TripUser;
02-17 10:23:50.260: DEBUG/com.idatt.json.JsonWrapper(12004): ------------- Jackson Wins by 1 object: [Lcom.idatt.json.TripUpdate;
02-17 10:24:00.455: DEBUG/com.idatt.json.JsonWrapper(12004): ------------- GSON Wins by 45 object: java.lang.Integer
02-17 10:24:00.541: DEBUG/com.idatt.json.JsonWrapper(12004): ------------- GSON Wins by 34 object: [Lcom.idatt.json.Device;

Ответы [ 2 ]

6 голосов
/ 17 февраля 2012

Чтобы попытаться нормализовать различия, связанные с поведением VM Dynamic, а также с горячей / холодной JVM, попробуйте синхронизировать каждый цикл, выполняющийся 10000 раз, и посмотрите, в чем разница.

Также обратите внимание, что первый набор запуска кода будет отличаться по времени от второго набора только из-за случайности ВМ; так что переверните их, а затем усредните время.

Net-net, я сомневаюсь, что вы найдете существенную разницу.

В сторону: если миллисекунды имеют большое значение, посмотрите на анализ потока, который Джексон и GSON обеспечивают для более быстрого необработанного доступа (но вы будете отвечать за анализ логики и восстановление ваших объектов, которые могут быть чистыми потерями)

1 голос
/ 19 февраля 2012

Обычные предупреждения здесь (в Google вы найдете советы по измерению производительности Java, если они новые):

  • Вы ДОЛЖНЫ выполнить достаточно измерений для стабилизации результатов синхронизации - JVM требуется некоторое время для оптимизации кода (компиляция из байт-кода в нативный). Это означает, что по крайней мере 10 секунд или около того, прежде чем проводить какие-либо измерения
  • Не передавайте строки, если только ваши входные данные не должны быть представлены как строки - накладные расходы на чтение ввода, преобразование в строку обычно не требуется, и самый быстрый способ - передать InputStream или byte[]' (or, for parsers that accept neither, Reader built from InputStream`
  • (несовершеннолетний) Не конструировать Date с; просто используйте System.currentTimeMillis() (или 'timeNanos`) для получения времени.

Я предполагаю, что вы, возможно, забыли первую часть, и поэтому результаты несколько произвольны и меняются от прогона к прогону.

...