Я пытаюсь протестировать матрицы, а не использовать обычные методы для точечных данных, чтобы увидеть, что быстрее. Я генерирую точечные данные и пытаюсь преобразовать / сопоставить их из декартовых координат в координаты экрана, а затем выполнить 2 теста, чтобы выяснить, какой из них быстрее. Я сомневаюсь, что моя реализация формулы преобразования сделана хорошо с использованием класса Matrix в Android, так как я совсем новичок в ее использовании, но он дает те же результаты, что и обычные методы getScreenX () и getScreenY ().
Трудно тестировать с матрицами, потому что он продолжает объединять результаты в массив точек из предыдущих итераций, поэтому я должен использовать клонированные массивы, чтобы избежать этого, что, вероятно, приводит к снижению производительности.
Я надеялся, что использование матриц улучшит производительность на точечных данных, но результаты показывают, что это намного медленнее, чем использование обычных методов с простыми математическими операциями. Или это может быть только из-за того, как я это реализовал. Я также хотел бы выполнить другие преобразования точечных данных, которые связаны с матрицами, но если они не дают никаких преимуществ в производительности, мне придется прибегнуть к использованию обычной математики в Java.
Есть ли способ улучшить производительность преобразования координат, используя класс Matrix androids или любые другие библиотеки производительности матрицы для Java?
Также был бы признателен, если бы была возможна дальнейшая оптимизация для моих методов преобразования getScreenX () и getScreenY (), например, переписать их другим способом, который мог бы ускорить их немного дальше, если класс Matrix не собирается к.
код
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
offsetX = 1;
offsetY = 2;
scaleX = 3;
scaleY = ((float)(height/width))*scaleX;
/* was part of the conversion method originally,
but can be taken out and calculated beforehand
to improve performance slightly rather than calculating
multiple times in the getScreen conversion methods
*/
halfWidthScaleX = (halfWidth/scaleX);
halfHeightScaleY = (halfHeight/scaleY);
/* start tests */
test();
}
private static final int RUNS = 10000; /* no. of test runs */
int width = 720, height = 1280;
int halfWidth = width/2;
int halfHeight = height/2;
float offsetX, offsetY; /* math coordinate offset from origin */
float scaleX, scaleY;
float halfWidthScaleX, halfHeightScaleY;
/* covert cartesian coordinates to screen coordinates methods */
private float getScreenX(float x){
return halfWidth + (x-offsetX)*halfWidthScaleX;
}
private float getScreenY(float y){
return halfHeight - (y-offsetY)*halfHeightScaleY;
}
private void test(){
/* create points data */
float[] points = new float[64];
float epsilon = 0;
float pairSize = points.length/2;
for (int i = 0; i < pairSize; i++){
/* 1st point is x coordinate, 2nd point is y coordinate */
points[i] = epsilon;
points[i+1] = (float) Math.sin(epsilon);
epsilon += 0.1;
}
float[] pointsClone = points.clone();
/* test 1 - screen methods test */
/* sum used to compare calculation results in both tests, both should be the same */
float sum = 0;
long startTime = System.nanoTime();
for (int r = 0; r < RUNS; r++){
/* loop through pairs of point data */
for (int i = 0; i < pairSize; i += 2){
sum += getScreenX(points[i]);
sum += getScreenY(points[i+1]);
}
}
long test1Time = System.nanoTime() - startTime;
Log.i(TAG, "test: test 1 sum = "+sum);
/* test 2 - matrix methods test */
sum = 0;
startTime = System.nanoTime();
for (int r = 0; r < RUNS; r++){
points = mapArray(pointsClone);
/* loop through pairs of point data */
for (int i = 0; i < pairSize; i += 2){
sum += points[i];
sum += points[i+1];
}
}
long test2Time = System.nanoTime() - startTime;
Log.i(TAG, "test: test 2 sum = "+sum);
/* result */
Log.i(TAG, "test: test 1 time = "+(test1Time/RUNS)+", test 2 time = "+(test2Time/RUNS));
}
private float[] mapArray(float[] array) {
float[] cloned = array.clone();
/* recreate the conversion formula with a matrix */
Matrix matrix = new Matrix();
matrix.preTranslate(-offsetX,-offsetY);
matrix.postScale(halfWidthScaleX, halfHeightScaleY);
matrix.mapPoints(cloned);
matrix.reset();
matrix.postTranslate(halfWidth,-halfHeight);
matrix.postScale(1,-1); /* flip sign on y coordinates */
matrix.mapPoints(cloned);
matrix.reset();
return cloned;
}
}