001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2016 ForgeRock AS.
015 */
016
017package org.forgerock.http.serialization;
018
019import static org.forgerock.json.JsonValue.array;
020import static org.forgerock.json.JsonValue.field;
021import static org.forgerock.json.JsonValue.json;
022import static org.forgerock.json.JsonValue.object;
023
024import java.io.IOException;
025import java.util.concurrent.TimeUnit;
026
027import org.forgerock.http.util.Json;
028import org.forgerock.json.JsonValue;
029import org.forgerock.util.i18n.LocalizableString;
030import org.forgerock.util.i18n.PreferredLocales;
031import org.openjdk.jmh.annotations.Benchmark;
032import org.openjdk.jmh.annotations.BenchmarkMode;
033import org.openjdk.jmh.annotations.Fork;
034import org.openjdk.jmh.annotations.Measurement;
035import org.openjdk.jmh.annotations.Mode;
036import org.openjdk.jmh.annotations.OutputTimeUnit;
037import org.openjdk.jmh.annotations.Scope;
038import org.openjdk.jmh.annotations.State;
039import org.openjdk.jmh.annotations.Warmup;
040import org.openjdk.jmh.runner.Runner;
041import org.openjdk.jmh.runner.RunnerException;
042import org.openjdk.jmh.runner.options.Options;
043import org.openjdk.jmh.runner.options.OptionsBuilder;
044
045import com.fasterxml.jackson.databind.ObjectMapper;
046
047@State(Scope.Thread)
048@BenchmarkMode(Mode.AverageTime)
049@OutputTimeUnit(TimeUnit.NANOSECONDS)
050@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
051@Measurement(iterations = 1, time = 10, timeUnit = TimeUnit.SECONDS)
052public class JacksonJsonSerialization {
053
054    private static final JsonValue TARGET = json(object(
055            field("string", "a string"),
056            field("number", 145.644D),
057            field("bool", true),
058            field("obj", object(
059                    field("localizable", new LocalizableString("not localizable"))
060            )),
061            field("array", json(array(
062                    "1",
063                    "2",
064                    "3"
065            )))
066    ));
067
068    private static final PreferredLocales LOCALES = new PreferredLocales();
069
070    private static final ObjectMapper MAPPER = new ObjectMapper()
071            .registerModules(new Json.JsonValueModule(), new Json.LocalizableStringModule());
072
073    @Benchmark
074    public byte[] testDefaultJson() throws IOException {
075        return Json.writeJson(TARGET);
076    }
077
078    @Benchmark
079    public byte[] testConstructObjectMapperEachTime() throws IOException {
080        return new ObjectMapper()
081                .registerModules(new Json.JsonValueModule(), new Json.LocalizableStringModule())
082                .writeValueAsBytes(TARGET);
083    }
084
085    @Benchmark
086    public byte[] testWithAttribute() throws IOException {
087        return Json.makeLocalizingObjectWriter(MAPPER, LOCALES).writeValueAsBytes(TARGET);
088    }
089
090    public static void main(String[] args) throws RunnerException {
091        Options opt = new OptionsBuilder()
092                .include(JacksonJsonSerialization.class.getSimpleName())
093                .build();
094
095        new Runner(opt).run();
096    }
097
098}