Skip to content

Commit 7dc7055

Browse files
Jonathan727halfhp
authored andcommitted
Many Performance Improvements (halfhp#47)
* Corrected documentation for `OrderedXYSeries` * Rename local variable in SeriesUtils.java to better describe its contents. Android studio also replaced wildcards in imports probably to match AOSP style guides https://source.android.com/source/code-style#fully-qualify-imports * Implements `toString` methods for `RectRegion` and related classes for easier debugging. * Refactoring only - reduced nesting in XYConstraints.java * Rename local variable in SeriesUtils.java to better describe its contents. Android studio also replaced wildcards in imports probably to match AOSP style guides https://source.android.com/source/code-style#fully-qualify-imports * Implements `toString` methods for `RectRegion` and related classes for easier debugging. * Refactoring only - reduced nesting in XYConstraints.java * Added shortcut to XYConstraints.java#contains for situations where there are no defined constraints. This avoids getting the double value of two numbers. * Removed redundant array creation in Redrawer.java * Replaced manual array copy operations with possibly faster method (will vary by android device) * Fixed `FastLineAndPointRenderer` allocating many extra instances of `PointF` which hurts android performance. * Prevent creation of a new instance of `FastNumber` when setting the min or max of a `Region` * Replaced empty string concatenation with more efficient `String.valueOf` * Replaced HashMaps with EnumMaps where possible in XYGraphWidget.java * Replaced stringbuffer with string in XYConstraints.java#toString() * Replaced HashSet with EnumSet * Replace float new instance with Float.valueOf * Replaced StringBuffer with StringBuilder * set initial array sizes * Removed the primative cache from FastNumber#equals and FastNumber#hashcode() and made the number field final * Made methods static where possible * Add Unit Tests for FastNumber.java#equals and FastNumber.java#hashCode * FastNumber.java does not allow null * Annotated all method/parameters in overrides which aren't annotated as the method/parameter they override. * Inferred nullity annotations for `FastNumber` and `FixedSizeEditableXYSeries` * fix typo * Simplified unit tests for FastNumberTest.java
1 parent ef94704 commit 7dc7055

24 files changed

Lines changed: 380 additions & 117 deletions

androidplot-core/src/main/java/com/androidplot/Region.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ public void setMin(Number min) {
215215
} else {
216216
this.min = null;
217217
}
218-
} else {
218+
} else if (this.min == null || !this.min.equals(min)) {
219219
this.min = new FastNumber(min);
220220
}
221221
}
@@ -237,7 +237,7 @@ public void setMax(Number max) {
237237
} else {
238238
this.max = null;
239239
}
240-
} else {
240+
} else if (this.max == null || !this.max.equals(max)) {
241241
this.max = new FastNumber(max);
242242
}
243243
}
@@ -252,7 +252,7 @@ public boolean isDefined() {
252252

253253
@Override
254254
public String toString() {
255-
final StringBuffer sb = new StringBuffer("Region{");
255+
final StringBuilder sb = new StringBuilder("Region{");
256256
sb.append("min=").append(min);
257257
sb.append(", max=").append(max);
258258
sb.append(", cachedLength=").append(cachedLength);

androidplot-core/src/main/java/com/androidplot/SeriesRegistry.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import com.androidplot.ui.Formatter;
2020
import com.androidplot.ui.SeriesBundle;
2121

22-
import java.io.*;
22+
import java.io.Serializable;
2323
import java.util.ArrayList;
2424
import java.util.Iterator;
2525
import java.util.List;
@@ -38,7 +38,7 @@ public List<BundleType> getSeriesAndFormatterList() {
3838
return registry;
3939
}
4040
public List<SeriesType> getSeriesList() {
41-
List<SeriesType> result = new ArrayList<>();
41+
List<SeriesType> result = new ArrayList<>(registry.size());
4242
for(SeriesBundle<SeriesType, FormatterType> sfPair : registry) {
4343
result.add(sfPair.getSeries());
4444
}

androidplot-core/src/main/java/com/androidplot/ui/DynamicTableModel.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,10 @@ public TableModelIterator(DynamicTableModel dynamicTableModel, RectF tableRect,
149149
calculatedRows = dynamicTableModel.getNumRows();
150150

151151
// round up:
152-
calculatedColumns = new Float((totalElements / (float) calculatedRows) + 0.5).intValue();
152+
calculatedColumns = Float.valueOf((totalElements / (float) calculatedRows) + 0.5f).intValue();
153153
} else if(dynamicTableModel.getNumRows() == 0 && dynamicTableModel.getNumColumns() >= 1) {
154154
calculatedColumns = dynamicTableModel.getNumColumns();
155-
calculatedRows = new Float((totalElements / (float) calculatedColumns) + 0.5).intValue();
155+
calculatedRows = Float.valueOf((totalElements / (float) calculatedColumns) + 0.5f).intValue();
156156
// unlimited rows and columns (impossible) so default a single row with n columns:
157157
}else if(dynamicTableModel.getNumColumns() == 0 && dynamicTableModel.getNumRows() == 0) {
158158
calculatedRows = 1;

androidplot-core/src/main/java/com/androidplot/ui/LayoutManager.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,15 @@
1616

1717
package com.androidplot.ui;
1818

19-
import android.graphics.*;
19+
import android.graphics.Canvas;
20+
import android.graphics.Color;
21+
import android.graphics.Paint;
22+
import android.graphics.PointF;
23+
import android.graphics.RectF;
24+
import android.graphics.Region;
2025
import android.view.MotionEvent;
2126
import android.view.View;
27+
2228
import com.androidplot.exception.PlotRenderException;
2329
import com.androidplot.ui.widget.Widget;
2430
import com.androidplot.util.DisplayDimensions;
@@ -132,7 +138,7 @@ public void draw(Canvas canvas) throws PlotRenderException {
132138
}
133139
}
134140

135-
private void drawSpacing(Canvas canvas, RectF outer, RectF inner, Paint paint) {
141+
private static void drawSpacing(Canvas canvas, RectF outer, RectF inner, Paint paint) {
136142
try {
137143
canvas.save(Canvas.ALL_SAVE_FLAG);
138144
canvas.clipRect(inner, Region.Op.DIFFERENCE);

androidplot-core/src/main/java/com/androidplot/ui/PositionMetrics.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package com.androidplot.ui;
1818

19+
import android.support.annotation.NonNull;
20+
1921
public class PositionMetrics implements Comparable<PositionMetrics> {
2022

2123
private HorizontalPosition horizontalPosition;
@@ -47,7 +49,7 @@ public void setAnchor(Anchor anchor) {
4749
}
4850

4951
@Override
50-
public int compareTo(PositionMetrics o) {
52+
public int compareTo(@NonNull PositionMetrics o) {
5153
if(this.layerDepth < o.layerDepth) {
5254
return -1;
5355
} else if(this.layerDepth == o.layerDepth) {

androidplot-core/src/main/java/com/androidplot/util/FastNumber.java

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package com.androidplot.util;
22

3+
import android.support.annotation.NonNull;
4+
import android.support.annotation.Nullable;
5+
36
/**
47
* An extension of {@link Number} optimized for speed at the cost of memory.
58
*/
69
public class FastNumber extends Number {
710

8-
private Number number;
11+
@NonNull
12+
private final Number number;
913
private boolean hasDoublePrimitive;
1014
private boolean hasFloatPrimitive;
1115
private boolean hasIntPrimitive;
@@ -14,7 +18,11 @@ public class FastNumber extends Number {
1418
private float floatPrimitive;
1519
private int intPrimitive;
1620

17-
public FastNumber(Number number) {
21+
public FastNumber(@NonNull Number number) {
22+
//noinspection ConstantConditions //in case someone ignores the @NonNull annotation
23+
if (number == null) {
24+
throw new IllegalArgumentException("number parameter cannot be null");
25+
}
1826

1927
// avoid nested instances of FastNumber :
2028
if(number instanceof FastNumber) {
@@ -64,6 +72,33 @@ public double doubleValue() {
6472
return doublePrimitive;
6573
}
6674

75+
/**
76+
* To be equal, two instances must both be instances of {@link FastNumber}. The inner {@link
77+
* #number} field must also be a common type. Numbers which are mathematically equal are not
78+
* necessarily equal. This keeps with the java implementation of common Number classes where for
79+
* instance {@code new Integer(0).equals(new Double(0))} returns {@code false}
80+
*/
81+
@Override
82+
public boolean equals(@Nullable Object o) {
83+
if (this == o) {
84+
return true;
85+
}
86+
if (o == null || getClass() != o.getClass()) {
87+
return false;
88+
}
89+
90+
FastNumber that = (FastNumber) o;
91+
92+
return number.equals(that.number);
93+
94+
}
95+
96+
@Override
97+
public int hashCode() {
98+
return number.hashCode();
99+
}
100+
101+
@NonNull
67102
@Override
68103
public String toString() {
69104
return String.valueOf(doubleValue());

androidplot-core/src/main/java/com/androidplot/util/Redrawer.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717
package com.androidplot.util;
1818

1919
import android.util.Log;
20+
2021
import com.androidplot.Plot;
2122

2223
import java.lang.ref.WeakReference;
2324
import java.util.ArrayList;
24-
import java.util.Arrays;
25+
import java.util.Collections;
2526
import java.util.List;
2627

2728
/**
@@ -52,7 +53,7 @@ public class Redrawer implements Runnable {
5253
* @param startImmediately If true, invokes run() immediately after construction.
5354
*/
5455
public Redrawer(List<Plot> plots, float maxRefreshRate, boolean startImmediately) {
55-
this.plots = new ArrayList<>();
56+
this.plots = new ArrayList<>(plots.size());
5657
for(Plot plot : plots) {
5758
this.plots.add(new WeakReference<>(plot));
5859
}
@@ -65,7 +66,7 @@ public Redrawer(List<Plot> plots, float maxRefreshRate, boolean startImmediately
6566
}
6667

6768
public Redrawer(Plot plot, float maxRefreshRate, boolean startImmediately) {
68-
this(Arrays.asList(new Plot[]{plot}), maxRefreshRate, startImmediately);
69+
this(Collections.singletonList(plot), maxRefreshRate, startImmediately);
6970
}
7071

7172
/**
@@ -121,7 +122,7 @@ public void run() {
121122
}
122123
}
123124
}
124-
} catch(InterruptedException e) {
125+
} catch (InterruptedException ignored) {
125126

126127
} finally {
127128
Log.d(TAG, "Redrawer thread exited.");

androidplot-core/src/main/java/com/androidplot/xy/BubbleFormatter.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@
1616

1717
package com.androidplot.xy;
1818

19-
import android.content.*;
20-
import android.graphics.*;
19+
import android.content.Context;
20+
import android.graphics.Color;
21+
import android.graphics.Paint;
2122

22-
import com.androidplot.ui.*;
23-
import com.androidplot.util.*;
23+
import com.androidplot.ui.SeriesRenderer;
24+
import com.androidplot.util.PixelUtils;
2425

2526
/**
2627
* Format for drawing a value using {@link BubbleRenderer}.
@@ -51,7 +52,7 @@ public class BubbleFormatter extends XYSeriesFormatter<XYRegionFormatter> {
5152
setPointLabeler(new PointLabeler<BubbleSeries>() {
5253
@Override
5354
public String getLabel(BubbleSeries series, int index) {
54-
return series.getZ(index) + "";
55+
return String.valueOf(series.getZ(index));
5556
}
5657
});
5758
}

androidplot-core/src/main/java/com/androidplot/xy/FastLineAndPointRenderer.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@
1616

1717
package com.androidplot.xy;
1818

19-
import android.graphics.*;
19+
import android.graphics.Canvas;
20+
import android.graphics.PointF;
21+
import android.graphics.RectF;
22+
2023
import com.androidplot.exception.PlotRenderException;
2124
import com.androidplot.ui.RenderStack;
2225
import com.androidplot.ui.SeriesRenderer;
2326

24-
import java.util.*;
27+
import java.util.ArrayList;
28+
import java.util.List;
2529

2630
/**
2731
* A faster implementation of of {@link LineAndPointRenderer}. For performance reasons, has these constraints:
@@ -53,21 +57,21 @@ protected void onRender(Canvas canvas, RectF plotArea, XYSeries series, Formatte
5357

5458
int segmentLen = 0;
5559
boolean isLastPointNull = true;
60+
PointF resultPoint = new PointF();
5661
for (int i = 0, j = 0; i < series.size(); i++, j+=2) {
5762
Number y = series.getY(i);
5863
Number x = series.getX(i);
5964

60-
PointF thisPoint;
6165
if (y != null && x != null) {
6266
if(isLastPointNull) {
6367
segmentOffsets.add(j);
6468
segmentLen = 0;
6569
isLastPointNull = false;
6670
}
6771

68-
thisPoint = getPlot().getBounds().transformScreen(x, y, plotArea);
69-
points[j] = thisPoint.x;
70-
points[j+1] = thisPoint.y;
72+
getPlot().getBounds().transformScreen(resultPoint, x, y, plotArea);
73+
points[j] = resultPoint.x;
74+
points[j + 1] = resultPoint.y;
7175
segmentLen+=2;
7276

7377
// if this is the last point, account for it in segment lengths:

androidplot-core/src/main/java/com/androidplot/xy/FixedSizeEditableXYSeries.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package com.androidplot.xy;
22

3-
import com.androidplot.util.*;
3+
import android.support.annotation.NonNull;
44

5-
import java.util.*;
5+
import com.androidplot.util.FastNumber;
6+
7+
import java.util.ArrayList;
8+
import java.util.List;
69

710
/**
811
* An efficient implementation of {@link EditableXYSeries} intended for use cases where
@@ -14,7 +17,9 @@
1417
*/
1518
public class FixedSizeEditableXYSeries implements EditableXYSeries {
1619

20+
@NonNull
1721
private List<FastNumber> xVals = new ArrayList<>();
22+
@NonNull
1823
private List<FastNumber> yVals = new ArrayList<>();
1924
private String title;
2025

@@ -24,12 +29,12 @@ public FixedSizeEditableXYSeries(String title, int size) {
2429
}
2530

2631
@Override
27-
public void setX(Number x, int index) {
32+
public void setX(@NonNull Number x, int index) {
2833
xVals.set(index, new FastNumber(x));
2934
}
3035

3136
@Override
32-
public void setY(Number y, int index) {
37+
public void setY(@NonNull Number y, int index) {
3338
yVals.set(index, new FastNumber(y));
3439
}
3540

@@ -44,7 +49,7 @@ public void resize(int size) {
4449
resize(yVals, size);
4550
}
4651

47-
protected void resize(List list, int size) {
52+
protected void resize(@NonNull List list, int size) {
4853
if (size > list.size()) {
4954
while (list.size() < size) {
5055
list.add(null);

0 commit comments

Comments
 (0)