diff --git a/src/jmh/java/com/amazon/ion/IonSystemBuilderCopyBenchmark.java b/src/jmh/java/com/amazon/ion/IonSystemBuilderCopyBenchmark.java new file mode 100644 index 000000000..c68685b27 --- /dev/null +++ b/src/jmh/java/com/amazon/ion/IonSystemBuilderCopyBenchmark.java @@ -0,0 +1,45 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +package com.amazon.ion; + +import com.amazon.ion.system.IonSystemBuilder; +import com.amazon.ion.system.SimpleCatalog; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +/** + * Measures the cost of copying an {@link IonSystemBuilder}. + */ +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Fork(value = 1) +@Warmup(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@State(Scope.Benchmark) +public class IonSystemBuilderCopyBenchmark { + + private final IonCatalog catalog = new SimpleCatalog(); + + @Benchmark + public IonSystemBuilder copy() { + return IonSystemBuilder.standard().copy(); + } + + @Benchmark + public IonSystemBuilder withCatalog() { + return IonSystemBuilder.standard().withCatalog(catalog); + } + + @Benchmark + public IonSystem buildWithCatalog() { + return IonSystemBuilder.standard().withCatalog(catalog).build(); + } +} diff --git a/src/main/java/com/amazon/ion/system/IonSystemBuilder.java b/src/main/java/com/amazon/ion/system/IonSystemBuilder.java index 8b8e57146..b48bf4339 100644 --- a/src/main/java/com/amazon/ion/system/IonSystemBuilder.java +++ b/src/main/java/com/amazon/ion/system/IonSystemBuilder.java @@ -91,15 +91,25 @@ public static IonSystemBuilder standard() IonCatalog myCatalog; boolean myStreamCopyOptimized = false; - IonTextWriterBuilder textWriterBuilder = IonTextWriterBuilder.standard().withCharsetAscii(); - IonBinaryWriterBuilder binaryWriterBuilder = IonBinaryWriterBuilder.standard(); - IonReaderBuilder readerBuilder = IonReaderBuilder.standard(); + // These are deliberately declared without initializers; their defaults are + // assigned by the no-argument constructor. See the note there. + IonTextWriterBuilder textWriterBuilder; + IonBinaryWriterBuilder binaryWriterBuilder; + IonReaderBuilder readerBuilder; /** You no touchy. */ private IonSystemBuilder() { - // empty + // The defaults are assigned here rather than in field initializers + // because Java runs field initializers as part of *every* constructor, + // including the copy constructor below, whose body then overwrites all + // three fields. That made copy() -- and therefore mutable(), + // immutable(), and every withXxx() -- allocate a full set of default + // writer/reader builders only to immediately discard them. + textWriterBuilder = IonTextWriterBuilder.standard().withCharsetAscii(); + binaryWriterBuilder = IonBinaryWriterBuilder.standard(); + readerBuilder = IonReaderBuilder.standard(); } private IonSystemBuilder(IonSystemBuilder that) diff --git a/src/test/java/com/amazon/ion/system/IonSystemBuilderTest.java b/src/test/java/com/amazon/ion/system/IonSystemBuilderTest.java index 6e0379f27..f9d916656 100644 --- a/src/test/java/com/amazon/ion/system/IonSystemBuilderTest.java +++ b/src/test/java/com/amazon/ion/system/IonSystemBuilderTest.java @@ -1,23 +1,10 @@ -/* - * Copyright 2007-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazon.ion.system; import static com.amazon.ion.impl.lite._Private_LiteDomTrampoline.isLiteSystem; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; @@ -201,5 +188,30 @@ public void testCopy() assertNotSame(b1, b2); assertSame(b1.getCatalog(), b2.getCatalog()); assertSame(b1.isStreamCopyOptimized(), b2.isStreamCopyOptimized()); + assertSame(b1.getIonTextWriterBuilder(), b2.getIonTextWriterBuilder()); + assertSame(b1.getIonBinaryWriterBuilder(), b2.getIonBinaryWriterBuilder()); + assertSame(b1.getReaderBuilder(), b2.getReaderBuilder()); + } + + @Test + public void testStandardHasDefaultSubBuilders() + { + IonSystemBuilder b = IonSystemBuilder.standard(); + assertNotNull(b.getIonTextWriterBuilder()); + assertNotNull(b.getIonBinaryWriterBuilder()); + assertNotNull(b.getReaderBuilder()); + assertSame(IonTextWriterBuilder.ASCII, b.getIonTextWriterBuilder().getCharset()); + } + + @Test + public void testCopyCarriesTheSameDefaultSubBuilders() + { + IonSystemBuilder standard = IonSystemBuilder.standard(); + IonSystemBuilder copy = standard.copy().mutable().copy().immutable().mutable(); + assertNotSame(standard, copy); + assertSame(standard.getIonTextWriterBuilder(), copy.getIonTextWriterBuilder()); + assertSame(standard.getIonBinaryWriterBuilder(), copy.getIonBinaryWriterBuilder()); + assertSame(standard.getReaderBuilder(), copy.getReaderBuilder()); + assertSame(IonTextWriterBuilder.ASCII, copy.getIonTextWriterBuilder().getCharset()); } }