Eliminate allocs - PointD pooling (#1892)

Replace all "new PointD()" instantiations with PointD.getInstance() / PointD.recycleInstance() pairs. Helper methods overloaded to include void return / output PointD variable signatures.  Old methods remain as convenience, with notations that they return recyclable instances.
This commit is contained in:
Tony Patino 2016-06-28 14:26:27 -07:00
parent d299546ebd
commit fcf26aa6ad
12 changed files with 107 additions and 25 deletions

View file

@ -682,6 +682,8 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
xValue, yValue, (float) origin.x, (float) origin.y, duration);
addViewportJob(job);
PointD.recycleInstance(origin);
} else {
Log.e(LOG_TAG, "Unable to execute zoomAndCenterAnimated(...) on API level < 11");
}
@ -843,6 +845,8 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
getTransformer(axis), this, (float) bounds.x, (float) bounds.y, duration);
addViewportJob(job);
PointD.recycleInstance(bounds);
} else {
Log.e(LOG_TAG, "Unable to execute moveViewToAnimated(...) on API level < 11");
}
@ -910,6 +914,8 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
getTransformer(axis), this, (float) bounds.x, (float) bounds.y, duration);
addViewportJob(job);
PointD.recycleInstance(bounds);
} else {
Log.e(LOG_TAG, "Unable to execute centerViewToAnimated(...) on API level < 11");
}
@ -1183,6 +1189,7 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
}
/**
* Returns a recyclable PointD instance
* Returns the x and y values in the chart at the given touch point
* (encapsulated in a PointD). This method transforms pixel coordinates to
* coordinates / values in the chart. This is the opposite method to
@ -1193,10 +1200,17 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
* @return
*/
public PointD getValuesByTouchPoint(float x, float y, AxisDependency axis) {
return getTransformer(axis).getValuesByTouchPoint(x, y);
PointD result = PointD.getInstance(0,0);
getValuesByTouchPoint(x,y,axis,result);
return result;
}
public void getValuesByTouchPoint(float x, float y, AxisDependency axis, PointD outputPoint){
getTransformer(axis).getValuesByTouchPoint(x, y, outputPoint);
}
/**
* Returns a recyclable PointD instance
* Transforms the given chart values into pixels. This is the opposite
* method to getValuesByTouchPoint(...).
*
@ -1208,6 +1222,7 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
return getTransformer(axis).getPixelsForValues(x, y);
}
PointD pointForGetYValueByTouchPoint = PointD.getInstance(0,0);
/**
* Returns y value at the given touch position (must not necessarily be
* a value contained in one of the datasets)
@ -1217,7 +1232,9 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
* @return
*/
public float getYValueByTouchPoint(float x, float y, AxisDependency axis) {
return (float) getValuesByTouchPoint(x, y, axis).y;
getValuesByTouchPoint(x, y, axis, pointForGetYValueByTouchPoint);
float result = (float) pointForGetYValueByTouchPoint.y;
return result;
}
/**
@ -1250,6 +1267,7 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
return null;
}
protected PointD posForGetLowestVisibleX = PointD.getInstance(0,0);
/**
* Returns the lowest x-index (value on the x-axis) that is still visible on
* the chart.
@ -1258,11 +1276,13 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
*/
@Override
public float getLowestVisibleX() {
PointD pos = getTransformer(AxisDependency.LEFT).getValuesByTouchPoint(mViewPortHandler.contentLeft(),
mViewPortHandler.contentBottom());
return (float) Math.max(mXAxis.mAxisMinimum, pos.x);
getTransformer(AxisDependency.LEFT).getValuesByTouchPoint(mViewPortHandler.contentLeft(),
mViewPortHandler.contentBottom(), posForGetLowestVisibleX);
float result = (float) Math.max(mXAxis.mAxisMinimum, posForGetLowestVisibleX.x);
return result;
}
protected PointD posForGetHighestVisibleX = PointD.getInstance(0,0);
/**
* Returns the highest x-index (value on the x-axis) that is still visible
* on the chart.
@ -1271,9 +1291,10 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
*/
@Override
public float getHighestVisibleX() {
PointD pos = getTransformer(AxisDependency.LEFT).getValuesByTouchPoint(mViewPortHandler.contentRight(),
mViewPortHandler.contentBottom());
return (float) Math.min(mXAxis.mAxisMaximum, pos.x);
getTransformer(AxisDependency.LEFT).getValuesByTouchPoint(mViewPortHandler.contentRight(),
mViewPortHandler.contentBottom(), posForGetHighestVisibleX);
float result = (float) Math.min(mXAxis.mAxisMaximum, posForGetHighestVisibleX.x);
return result;
}
/**

View file

@ -196,18 +196,22 @@ public class HorizontalBarChart extends BarChart {
return getHighlighter().getHighlight(y, x); // switch x and y
}
protected PointD posForGetLowestVisibleX = PointD.getInstance(0,0);
@Override
public float getLowestVisibleX() {
PointD pos = getTransformer(AxisDependency.LEFT).getValuesByTouchPoint(mViewPortHandler.contentLeft(),
mViewPortHandler.contentBottom());
return (float) Math.max(mXAxis.mAxisMinimum, pos.y);
getTransformer(AxisDependency.LEFT).getValuesByTouchPoint(mViewPortHandler.contentLeft(),
mViewPortHandler.contentBottom(), posForGetLowestVisibleX);
float result = (float) Math.max(mXAxis.mAxisMinimum, posForGetLowestVisibleX.y);
return result;
}
protected PointD posForGetHighestVisibleX = PointD.getInstance(0,0);
@Override
public float getHighestVisibleX() {
PointD pos = getTransformer(AxisDependency.LEFT).getValuesByTouchPoint(mViewPortHandler.contentLeft(),
mViewPortHandler.contentTop());
return (float) Math.min(mXAxis.mAxisMaximum, pos.y);
getTransformer(AxisDependency.LEFT).getValuesByTouchPoint(mViewPortHandler.contentLeft(),
mViewPortHandler.contentTop(), posForGetHighestVisibleX);
float result = (float) Math.min(mXAxis.mAxisMaximum, posForGetHighestVisibleX.y);
return result;
}
/**

View file

@ -37,6 +37,8 @@ public class BarHighlighter extends ChartHighlighter<BarDataProvider> {
(float) pos.y);
}
PointD.recycleInstance(pos);
return high;
}
@ -78,6 +80,8 @@ public class BarHighlighter extends ChartHighlighter<BarDataProvider> {
high.getAxis()
);
PointD.recycleInstance(pixels);
return stackedHigh;
}
}

View file

@ -28,15 +28,20 @@ public class ChartHighlighter<T extends BarLineScatterCandleBubbleDataProvider>
@Override
public Highlight getHighlight(float x, float y) {
float xVal = (float) getValsForTouch(x, y).x;
PointD pos = getValsForTouch(x, y);
float xVal = (float) pos.x;
PointD.recycleInstance(pos);
Highlight high = getHighlightForX(xVal, x, y);
return high;
}
/**
* Returns a recyclable PointD instance.
* Returns the corresponding xPos for a given touch-position in pixels.
*
* @param x
* @param y
* @return
*/
protected PointD getValsForTouch(float x, float y) {

View file

@ -37,6 +37,8 @@ public class HorizontalBarHighlighter extends BarHighlighter {
(float) pos.x);
}
PointD.recycleInstance(pos);
return high;
}

View file

@ -133,6 +133,9 @@ public abstract class AxisRenderer extends Renderer {
min = (float) p1.y;
max = (float) p2.y;
}
PointD.recycleInstance(p1);
PointD.recycleInstance(p2);
}
computeAxisValues(min, max);

View file

@ -58,6 +58,9 @@ public class XAxisRenderer extends AxisRenderer {
min = (float) p1.x;
max = (float) p2.x;
}
PointD.recycleInstance(p1);
PointD.recycleInstance(p2);
}
computeAxisValues(min, max);

View file

@ -49,6 +49,9 @@ public class XAxisRendererHorizontalBarChart extends XAxisRenderer {
min = (float) p1.y;
max = (float) p2.y;
}
PointD.recycleInstance(p1);
PointD.recycleInstance(p2);
}
computeAxisValues(min, max);

View file

@ -51,6 +51,9 @@ public class YAxisRendererHorizontalBarChart extends YAxisRenderer {
yMin = (float) p2.x;
yMax = (float) p1.x;
}
PointD.recycleInstance(p1);
PointD.recycleInstance(p2);
}
computeAxisValues(yMin, yMax);

View file

@ -17,7 +17,7 @@ public final class FSize extends ObjectPool.Poolable{
private static ObjectPool<FSize> pool;
static {
pool = ObjectPool.create(500, new FSize(0,0));
pool = ObjectPool.create(256, new FSize(0,0));
}

View file

@ -1,17 +1,44 @@
package com.github.mikephil.charting.utils;
import java.util.List;
/**
* Point encapsulating two double values.
*
* @author Philipp Jahoda
*/
public class PointD {
public class PointD extends ObjectPool.Poolable {
private static ObjectPool<PointD> pool;
static {
pool = ObjectPool.create(64, new PointD(0,0));
}
public static PointD getInstance(double x, double y){
PointD result = pool.get();
result.x = x;
result.y = y;
return result;
}
public static void recycleInstance(PointD instance){
pool.recycle(instance);
}
public static void recycleInstances(List<PointD> instances){
pool.recycle(instances);
}
public double x;
public double y;
public PointD(double x, double y) {
protected ObjectPool.Poolable instantiate(){
return new PointD(0,0);
}
private PointD(double x, double y) {
this.x = x;
this.y = y;
}
@ -22,4 +49,4 @@ public class PointD {
public String toString() {
return "PointD, x: " + x + ", y: " + y;
}
}
}

View file

@ -355,7 +355,8 @@ public class Transformer {
float[] ptsBuffer = new float[2];
/**
* Returns the x and y values in the chart at the given touch point
* Returns a recyclable PointD instance.
* returns the x and y values in the chart at the given touch point
* (encapsulated in a PointD). This method transforms pixel coordinates to
* coordinates / values in the chart. This is the opposite method to
* getPixelsForValues(...).
@ -366,18 +367,24 @@ public class Transformer {
*/
public PointD getValuesByTouchPoint(float x, float y) {
PointD result = PointD.getInstance(0,0);
getValuesByTouchPoint(x,y,result);
return result;
}
public void getValuesByTouchPoint(float x, float y, PointD outputPoint){
ptsBuffer[0] = x;
ptsBuffer[1] = y;
pixelsToValue(ptsBuffer);
double xTouchVal = ptsBuffer[0];
double yTouchVal = ptsBuffer[1];
return new PointD(xTouchVal, yTouchVal);
outputPoint.x = ptsBuffer[0];
outputPoint.y = ptsBuffer[1];
}
/**
* Returns a recyclable PointD instance.
* Returns the x and y coordinates (pixels) for a given x and y value in the chart.
*
* @param x
@ -394,7 +401,7 @@ public class Transformer {
double xPx = ptsBuffer[0];
double yPx = ptsBuffer[1];
return new PointD(xPx, yPx);
return PointD.getInstance(xPx, yPx);
}
public Matrix getValueMatrix() {