简体   繁体   English

为什么这个Android代码这么慢?

[英]Why is this Android code so slow?

I have a contour plot rendering routine that is blazing fast. 我有一个等高线图呈现是超快的程序。 It basically renders to a form in the OnPaint event, and updates very quickly... basically as fast as you can move a mouse. 它基本上在OnPaint事件中呈现为表单,并且更新非常快...基本上与移动鼠标一样快。 I was very pleased with it. 我对此非常满意。 It's based on this paper: 它基于本文:

http://paulbourke.net/papers/conrec/ http://paulbourke.net/papers/conrec/

However, I ported it to Android/Java and targeted a very fast tablet (Nexus 9) and it is surprisingly slow, to the point where I feel like I must be using the wrong approach. 但是,我将其移植到Android / Java上,并针对非常快的平板电脑(Nexus 9)进行了调试,而且速度非常慢,以至于我觉得自己必须使用错误的方法。 Basically I: 基本上我:

1) create a view programmatically, 2) implement the onDraw method to call my cContourPlot class Draw method, which 3) iterates through a 2-D data array, compares to a 1-D "bins" array, and makes a few thousand calls to the "DrawPolygonRegion" function I wrote below. 1)以编程方式创建一个视图,2)实现onDraw方法以调用我的cContourPlot类Draw方法,其中3)遍历2D数据数组,与1D“ bins”数组进行比较,并进行数千次调用我在下面编写的“ DrawPolygonRegion”函数。

This takes a surprisingly long time, about 100x slower than in .NET., to the point where I am wondering if I'm doing something wrong. 这要花很长的时间,比.NET慢大约100倍,以至于我想知道自己做错了什么。 Specific questions: 具体问题:

a) Is the function below speed-tweakable? a)速度可调以下的功能吗? Is there a faster way to draw a polygon than using a Path? 有没有比使用路径更快的绘制多边形的方法? (in .NET there is a DrawPolygon function, had to make something new for the Android port) b) Do I need to do something to "batch" my rendering commands? (.NET中有一个DrawPolygon函数,必须为Android端口添加一些新功能)b)我是否需要做一些事情来“分批”渲染命令? Such as (imagined:) Canvas.SuspendUpdates, Canvas.ResumeUpdates? 如(想象中的:)Canvas.SuspendUpdates,Canvas.ResumeUpdates? c) Do I need to activate double buffering or something? c)是否需要激活双缓冲或其他功能? My quick research says this is done automatically in Android, but not sure. 我的快速研究表明,这是在Android中自动完成的,但不确定。 (I had to activate it in .NET but not sure if I have to here) (我必须在.NET中激活它,但不确定是否必须在这里激活)

Thanks a lot for any insight/help. 非常感谢您的任何见解/帮助。

void DrawPolygonRegion(Canvas c, int color, double ... p)
{
    int length = p.length;

    if (length >= 6)
    {
        paint.setColor(color);
        paint.setStyle(Style.FILL);
        Path path = new Path();
        path.moveTo((float) p[0], (float) p[1]); // used for first point
        path.lineTo((float) p[2], (float) p[3]);
        path.lineTo((float) p[4], (float) p[5]);

        int idx = 6;

        for (int n=6; n<length; n+=2)
        {
            path.lineTo((float) p[n], (float) p[n+1]);
        }

        c.drawPath(path, paint);
    }
}

Calling this a few thousand times. 叫了几千遍。 Oh yeah, you got some problems. 哦,是的,您遇到了一些问题。

1)It allocates a new Path. 1)分配一个新的路径。 Allocations add up quickly on Android. 分配在Android上迅速增加。 Try to avoid them. 尽量避免它们。 Prefer to reuse objects, especially in functions like onDraw. 最好重用对象,尤其是在onDraw之类的函数中。

2)You really ought to not be creating whole paths all the time anyway- they're better off saved and reused in append mode. 2)您真的不应该一直在创建整个路径-最好保存并在附加模式下重用它们。

3)Downcasting from double to float isn't free. 3)从双精度浮点数到浮点数的转换并非免费。 Avoid it 躲开它

4)Are you doing this directly to the screen Canvas? 4)您是直接在画布上执行此操作吗? Don't. 别。 Do it to a bitmap canvas in its own thread, and blit the results to the screen canvas. 在其自己的线程中对位图画布进行处理,然后将结果涂抹到屏幕画布上。

I really doubt this code is blazing fast even in .NET on a PC with a better processor and RAM. 我真的怀疑,即使是在具有更好处理器和RAM的PC上的.NET中,该代码能否快速运行。 I think your butt is being saved there by hardware acceleration. 我认为您的屁股被硬件加速保存在那里。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM