From 7b4db81c78842b5b23cb4a12456be31258363150 Mon Sep 17 00:00:00 2001 From: Brenschede Date: Fri, 28 Jun 2019 19:07:36 +0200 Subject: [PATCH] decoder performance --- .../java/btools/codec/StatCoderContext.java | 24 +++++++++- .../java/btools/util/BitCoderContext.java | 46 +++++++++++++++---- 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/brouter-codec/src/main/java/btools/codec/StatCoderContext.java b/brouter-codec/src/main/java/btools/codec/StatCoderContext.java index e964839..515efa4 100644 --- a/brouter-codec/src/main/java/btools/codec/StatCoderContext.java +++ b/brouter-codec/src/main/java/btools/codec/StatCoderContext.java @@ -9,6 +9,26 @@ public final class StatCoderContext extends BitCoderContext private static TreeMap statsPerName; private long lastbitpos = 0; + + private static final int[] noisy_bits = new int[1024]; + + static + { + // noisybits lookup + for( int i=0; i<1024; i++ ) + { + int p = i; + int noisybits = 0; + while (p > 2) + { + noisybits++; + p >>= 1; + } + noisy_bits[i] = noisybits; + } + } + + public StatCoderContext( byte[] ab ) { super( ab ); @@ -167,12 +187,12 @@ public final class StatCoderContext extends BitCoderContext { int p = predictor < 0 ? -predictor : predictor; int noisybits = 0; - while (p > 2) + while (p > 1023) { noisybits++; p >>= 1; } - return predictor + decodeNoisyDiff( noisybits ); + return predictor + decodeNoisyDiff( noisybits + noisy_bits[p] ); } /** diff --git a/brouter-util/src/main/java/btools/util/BitCoderContext.java b/brouter-util/src/main/java/btools/util/BitCoderContext.java index fa92c3e..1b88f29 100644 --- a/brouter-util/src/main/java/btools/util/BitCoderContext.java +++ b/brouter-util/src/main/java/btools/util/BitCoderContext.java @@ -10,6 +10,27 @@ public class BitCoderContext private int bits; // bits left in buffer (read mode) private int b; + private static final int[] vl_values = new int[4096]; + private static final int[] vl_length = new int[4096]; + + static + { + // fill varbits lookup table + + BitCoderContext bc = new BitCoderContext( new byte[4] ); + for( int i=0; i<4096; i++ ) + { + bc.reset(); + bc.bits = 14; + bc.b = 0x1000 + i; + + int b0 = bc.getReadingBitPosition(); + vl_values[i] = bc.decodeVarBits2(); + vl_length[i] = bc.getReadingBitPosition() - b0; + } + } + + public BitCoderContext( byte[] ab ) { this.ab = ab; @@ -69,21 +90,26 @@ public class BitCoderContext public final int decodeVarBits() { - int range = 1; - int cnt = 1; fillBuffer(); - if ( (b & 0xffffff ) == 0 ) + int b12 = b & 0xfff; + int len = vl_length[b12]; + if ( len <= 12 ) { - return decodeVarBits2(); // fast version limited to 24 bit + b >>>= len; + bits -= len; + return vl_values[b12]; // full value lookup } - while ((b & range) == 0) + if ( len <= 23 ) // // only length lookup { - range = (range << 1) | 1; - cnt++; + int len2 = len >> 1; + b >>>= (len2+1); + int mask = 0xffffffff >>> ( 32 - len2 ); + mask += b & mask; + b >>>= len2; + bits -= len; + return mask; } - b >>>= cnt; - bits -= cnt; - return (range >>> 1) + ( cnt > 1 ? decodeBits( cnt-1 ) : 0 ); + return decodeVarBits2(); }