All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.matteobertozzi.yajbe.Demo Maven / Gradle / Ivy

Go to download

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