commit a12e989e403cc1811a97631a630c37e76494528b Author: Karsten Loesing karsten.loesing@gmx.net Date: Tue May 27 20:57:51 2014 +0200
Store bandwidth histories more efficiently.
We were storing bandwidth histories in TreeMap<Long, Long>() with keys being time in millis and values being bandwidth values. This showed up in profiles. It's far more (memory-)efficient to store bandwidth values in a long[] and put together the TreeMap when the caller requests it. And if the bandwidth history is evaluated exactly once, there should not even be a CPU overhead. --- .../descriptor/impl/BandwidthHistoryImpl.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/src/org/torproject/descriptor/impl/BandwidthHistoryImpl.java b/src/org/torproject/descriptor/impl/BandwidthHistoryImpl.java index 65def52..00953c0 100644 --- a/src/org/torproject/descriptor/impl/BandwidthHistoryImpl.java +++ b/src/org/torproject/descriptor/impl/BandwidthHistoryImpl.java @@ -47,15 +47,14 @@ public class BandwidthHistoryImpl implements BandwidthHistory { values = partsNoOpt[4].substring(2).split(",", -1); } if (values != null) { - long endMillis = this.historyEndMillis; + this.bandwidthValues = new long[values.length]; for (int i = values.length - 1; i >= 0; i--) { long bandwidthValue = Long.parseLong(values[i]); if (bandwidthValue < 0L) { throw new DescriptorParseException("Negative bandwidth " + "values are not allowed in line '" + line + "'."); } - this.bandwidthValues.put(endMillis, bandwidthValue); - endMillis -= this.intervalLength * 1000L; + this.bandwidthValues[i] = bandwidthValue; } isValid = true; } @@ -85,10 +84,17 @@ public class BandwidthHistoryImpl implements BandwidthHistory { return this.intervalLength; }
- private SortedMap<Long, Long> bandwidthValues = - new TreeMap<Long, Long>(); + private long[] bandwidthValues; public SortedMap<Long, Long> getBandwidthValues() { - return new TreeMap<Long, Long>(this.bandwidthValues); + SortedMap<Long, Long> result = new TreeMap<Long, Long>(); + if (this.bandwidthValues != null) { + long endMillis = this.historyEndMillis; + for (int i = this.bandwidthValues.length - 1; i >= 0; i--) { + result.put(endMillis, bandwidthValues[i]); + endMillis -= this.intervalLength * 1000L; + } + } + return result; } }