ARTEMIS-5048 use java.util.Base64
We've traditionally used org.apache.activemq.artemis.utils.Base64 for Base64 encoding/decoding. This implementation is based on public domain code from http://iharder.net/base64. In Java 8 java.util.Base64 was introduced. I assumed we hadn't switched to this implementation for performance reasons so I created a simple JMH-based test to compare the two implementations and it appears to me that java.util.Base64 is significantly faster than our current implementation. Using the JDK's class will simplify our code and improve performance. Also, it should be 100% backwards compatible since Base64 encoding/decoding is standardized.
This commit is contained in:
parent
6d84f3741e
commit
d9d84f814c
|
@ -292,7 +292,7 @@ public class DecodeJournal extends LockAbstract {
|
|||
}
|
||||
|
||||
private static byte[] decode(final String data) {
|
||||
return Base64.decode(data, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
|
||||
return Base64.decode(data, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -185,7 +185,7 @@ public class EncodeJournal extends LockAbstract {
|
|||
}
|
||||
|
||||
private static String encode(final byte[] data) {
|
||||
return Base64.encodeBytes(data, 0, data.length, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
|
||||
return Base64.encodeBytes(data, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -288,7 +288,7 @@ public class XMLMessageImporter {
|
|||
}
|
||||
|
||||
private static byte[] decode(String data) {
|
||||
return Base64.decode(data, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
|
||||
return Base64.decode(data, true);
|
||||
}
|
||||
|
||||
private interface MessageBodyBytesProcessor {
|
||||
|
|
|
@ -100,6 +100,6 @@ public class XmlDataExporterUtil {
|
|||
}
|
||||
|
||||
protected static String encode(final byte[] data) {
|
||||
return Base64.encodeBytes(data, 0, data.length, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
|
||||
return Base64.encodeBytes(data, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -173,8 +173,8 @@
|
|||
<xsd:element type="bodyType" name="body">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
the body of the message (Base64 encoded using the Base64.DONT_BREAK_LINES and Base64.URL_SAFE options;
|
||||
see org.apache.activemq.artemis.utils.Base64.encodeBytes(byte[], int, int, int)); stored in a CDATA
|
||||
the body of the message (Base64 URL-safe encoded;
|
||||
see java.util.Base64.getUrlEncoder().encodeToString(String); stored in a CDATA
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -16,13 +16,6 @@
|
|||
*/
|
||||
package org.apache.activemq.artemis.api.core;
|
||||
|
||||
import org.apache.activemq.artemis.json.JsonArray;
|
||||
import org.apache.activemq.artemis.json.JsonArrayBuilder;
|
||||
import org.apache.activemq.artemis.json.JsonNumber;
|
||||
import org.apache.activemq.artemis.json.JsonObject;
|
||||
import org.apache.activemq.artemis.json.JsonObjectBuilder;
|
||||
import org.apache.activemq.artemis.json.JsonString;
|
||||
import org.apache.activemq.artemis.json.JsonValue;
|
||||
import javax.management.openmbean.CompositeData;
|
||||
import javax.management.openmbean.CompositeDataSupport;
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
@ -34,6 +27,13 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.activemq.artemis.json.JsonArray;
|
||||
import org.apache.activemq.artemis.json.JsonArrayBuilder;
|
||||
import org.apache.activemq.artemis.json.JsonNumber;
|
||||
import org.apache.activemq.artemis.json.JsonObject;
|
||||
import org.apache.activemq.artemis.json.JsonObjectBuilder;
|
||||
import org.apache.activemq.artemis.json.JsonString;
|
||||
import org.apache.activemq.artemis.json.JsonValue;
|
||||
import org.apache.activemq.artemis.utils.Base64;
|
||||
import org.apache.activemq.artemis.utils.JsonLoader;
|
||||
import org.apache.activemq.artemis.utils.ObjectInputStreamWithClassLoader;
|
||||
|
|
|
@ -42,7 +42,7 @@ public class XidImpl implements Xid, Serializable {
|
|||
|
||||
public static String toBase64String(final Xid xid) {
|
||||
byte[] data = XidImpl.toByteArray(xid);
|
||||
return Base64.encodeBytes(data, 0, data.length, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
|
||||
return Base64.encodeBytes(data, true);
|
||||
}
|
||||
|
||||
private static byte[] toByteArray(final Xid xid) {
|
||||
|
|
|
@ -72,7 +72,7 @@ public class CoreMessageTest {
|
|||
|
||||
@BeforeEach
|
||||
public void before() {
|
||||
BYTE_ENCODE = Unpooled.wrappedBuffer(Base64.decode(STRING_ENCODE, Base64.DONT_BREAK_LINES | Base64.URL_SAFE));
|
||||
BYTE_ENCODE = Unpooled.wrappedBuffer(Base64.decode(STRING_ENCODE, true));
|
||||
// some extra caution here, nothing else, to make sure we would get the same encoding back
|
||||
assertEquals(STRING_ENCODE, encodeString(BYTE_ENCODE.array()));
|
||||
BYTE_ENCODE.readerIndex(0).writerIndex(BYTE_ENCODE.capacity());
|
||||
|
@ -421,7 +421,7 @@ public class CoreMessageTest {
|
|||
}
|
||||
|
||||
private String encodeString(byte[] bytes) {
|
||||
return Base64.encodeBytes(bytes, 0, bytes.length, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
|
||||
return Base64.encodeBytes(bytes, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -576,7 +576,7 @@ public final class DescribeJournal {
|
|||
}
|
||||
|
||||
private static String encode(final byte[] data) {
|
||||
return Base64.encodeBytes(data, 0, data.length, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
|
||||
return Base64.encodeBytes(data, true);
|
||||
}
|
||||
|
||||
private static Xid toXid(final byte[] data) {
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
package org.apache.activemq.artemis.tests.performance.utils;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.activemq.artemis.utils.Base64;
|
||||
import org.apache.activemq.artemis.utils.RandomUtil;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Param;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.infra.Blackhole;
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@Fork(1)
|
||||
@Warmup(iterations = 3, time = 5, timeUnit = TimeUnit.SECONDS)
|
||||
@Measurement(iterations = 10, time = 5, timeUnit = TimeUnit.SECONDS)
|
||||
public class Base64Benchmark {
|
||||
|
||||
@Param({"1", "10", "100"})
|
||||
private static int length;
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
public static class Input {
|
||||
public byte[] bytesToEncode = RandomUtil.randomString().repeat(length).getBytes();
|
||||
public String stringToDecode = java.util.Base64.getUrlEncoder().encodeToString(bytesToEncode);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchmarkCustomBase64Encoding(Blackhole blackhole, Input input) {
|
||||
blackhole.consume(Base64.encodeBytes(input.bytesToEncode));
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchmarkJavaBase64Encoding(Blackhole blackhole, Input input) {
|
||||
blackhole.consume(java.util.Base64.getUrlEncoder().encodeToString(input.bytesToEncode));
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchmarkCustomBase64Decoding(Blackhole blackhole, Input input) {
|
||||
blackhole.consume(Base64.decode(input.stringToDecode));
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchmarkJavaBase64Decoding(Blackhole blackhole, Input input) {
|
||||
blackhole.consume(java.util.Base64.getUrlDecoder().decode(input.stringToDecode));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue