io.github.matteobertozzi.yajbe.Demo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jackson-dataformat-yajbe Show documentation
Show all versions of jackson-dataformat-yajbe Show documentation
YAJBE is a compact binary data format built to be a drop-in replacement for JSON (JavaScript Object Notation).
The newest version!
package io.github.matteobertozzi.yajbe;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPInputStream;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
public class Demo {
private static final ThreadLocal humanDecimalFormatter = ThreadLocal.withInitial(() -> new DecimalFormat("0.00"));
private static String decimalFormat(final String suffix, final double value) {
return humanDecimalFormatter.get().format(value) + suffix;
}
private static ArrayList dataSetPaths() {
final ArrayList testFiles = new ArrayList<>();
fetchTestDataSets(testFiles, new File("./test-data"));
return testFiles;
}
private static void fetchTestDataSets(final ArrayList testFiles, final File rootDir) {
final File[] dirFiles = rootDir.listFiles();
if (dirFiles == null) return;
for (final File file : dirFiles) {
if (file.isDirectory()) {
fetchTestDataSets(testFiles, file);
} else {
final String fileName = file.getName();
if (fileName.endsWith(".json")) {
testFiles.add(file);
} else if (fileName.endsWith(".json.gz")) {
testFiles.add(file);
}
}
}
}
public static String humanTimeSince(final long timeNano) {
return humanTime(System.nanoTime() - timeNano, TimeUnit.NANOSECONDS);
}
public static String humanTimeNanos(final long timeNs) {
if (timeNs < 1000) return (timeNs < 0) ? "unkown" : timeNs + "ns";
return humanTimeMicros(timeNs / 1000);
}
public static String humanTimeMicros(final long timeUs) {
if (timeUs < 1000) return (timeUs < 0) ? "unkown" : timeUs + "us";
return humanTimeMillis(timeUs / 1000);
}
public static String humanTimeMillis(final long timeDiff) {
return humanTime(timeDiff, TimeUnit.MILLISECONDS);
}
public static String humanTimeSeconds(final long timeDiff) {
return humanTime(timeDiff, TimeUnit.SECONDS);
}
public static String humanTime(final long timeDiff, final TimeUnit unit) {
final long msec = unit.toMillis(timeDiff);
if (msec == 0) {
final long micros = unit.toMicros(timeDiff);
if (micros > 0) return micros + "us";
return unit.toNanos(timeDiff) + "ns";
}
if (msec < 1000) {
return msec + "ms";
}
final long hours = msec / (60 * 60 * 1000);
long rem = (msec % (60 * 60 * 1000));
final long minutes = rem / (60 * 1000);
rem = rem % (60 * 1000);
final float seconds = rem / 1000.0f;
if ((hours > 0) || (minutes > 0)) {
final StringBuilder buf = new StringBuilder(32);
if (hours > 0) {
buf.append(hours);
buf.append("hrs, ");
}
if (minutes > 0) {
buf.append(minutes);
buf.append("min, ");
}
final String humanTime;
if (seconds > 0) {
buf.append(decimalFormat("sec", seconds));
humanTime = buf.toString();
} else {
humanTime = buf.substring(0, buf.length() - 2);
}
if (hours > 24) {
return String.format("%s (%.1f days)", humanTime, (hours / 24.0));
}
return humanTime;
}
return String.format((seconds % 1) != 0 ? "%.4fsec" : "%.0fsec", seconds);
}
private static ObjectMapper newObjectMapper(final ObjectMapper mapper) {
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
mapper.setVisibility(PropertyAccessor.GETTER, Visibility.NONE);
mapper.setVisibility(PropertyAccessor.IS_GETTER, Visibility.NONE);
// --- Deserialization ---
// Just ignore unknown fields, don't stop parsing
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// Trying to deserialize value into an enum, don't fail on unknown value, use null instead
mapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);
// --- Serialization ---
// Don't include properties with null value in JSON output
mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
// Use default pretty printer
mapper.configure(SerializationFeature.INDENT_OUTPUT, false);
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
//mapper.setAnnotationIntrospector(new ExtentedAnnotationIntrospector());
return mapper;
}
private static final ObjectMapper JSON_MAPPER = newObjectMapper(new JsonMapper());
private static JsonNode parseFile(final File file) throws IOException {
if (file.getName().endsWith(".json.gz")) {
try (GZIPInputStream stream = new GZIPInputStream(new FileInputStream(file))) {
return JSON_MAPPER.readTree(stream);
}
}
if (file.getName().endsWith(".json")) {
return JSON_MAPPER.readTree(file);
}
throw new IllegalArgumentException("unsupported file " + file);
}
public static void main(final String[] args) throws Exception {
if (false) {
final ArrayList nodes = new ArrayList<>();
for (final File f: dataSetPaths()) {
nodes.add(parseFile(f));
}
final ObjectMapper yajbe = newObjectMapper(new YajbeMapper());
for (int k = 0; k < 10; ++k) {
final long startTime = System.nanoTime();
for (final JsonNode node: nodes) {
yajbe.writeValue(OutputStream.nullOutputStream(), node);
}
final long elapsed = System.nanoTime() - startTime;
System.out.println(nodes.size() + " -> " + humanTimeNanos(elapsed));
}
}
if (true) {
final Random rand = new Random();
final int[] iArray = new int[8 << 10];
for (int k = 0; k < iArray.length; ++k) {
iArray[k] = rand.nextInt();
}
final long[] lArray = new long[8 << 10];
for (int k = 0; k < lArray.length; ++k) {
lArray[k] = rand.nextLong();
}
if (true) {
final YajbeMapper mapper = new YajbeMapper();
//for (int z = 0; z < 5; ++z) {
while (true) {
final long startTime = System.nanoTime();
for (long k = 0; k < 100_000L; ++k) {
mapper.writeValue(OutputStream.nullOutputStream(), iArray);
mapper.writeValue(OutputStream.nullOutputStream(), lArray);
}
final long elapsed = System.nanoTime() - startTime;
System.out.println("v: " + humanTimeNanos(elapsed));
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy