简体   繁体   中英

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. I was very pleased with it. It's based on this paper:

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. 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.

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. Specific questions:

a) Is the function below speed-tweakable? 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? Such as (imagined:) Canvas.SuspendUpdates, Canvas.ResumeUpdates? c) Do I need to activate double buffering or something? My quick research says this is done automatically in Android, but not sure. (I had to activate it in .NET but not sure if I have to here)

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. Allocations add up quickly on Android. Try to avoid them. Prefer to reuse objects, especially in functions like 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.

3)Downcasting from double to float isn't free. Avoid it

4)Are you doing this directly to the screen Canvas? 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. I think your butt is being saved there by hardware acceleration.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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