为什么算法这么慢?

时间:2011-08-01 14:12:51

标签: android algorithm graph

我正在创建一个折线图,我最初使用的代码绘制速度很慢,以至于无用。我用在网上找到的代码替换它,它变得更快。我只是好奇为什么原始代码是如此之慢。下面发布的所有代码都在自定义视图的onDraw()方法中:

原始慢代码

    float yStart = 300f;

    for (int i=0; i < values.length; i++){              

        drawPath.moveTo(xStart, yStart);
        drawPath.lineTo(xStart+10, values[i]);
        drawPath.close();
        canvas.drawPath(drawPath, linePaint);

        xStart += 10;
        yStart = values[i]; 
    }

以后的快速代码

            float datalength = values.length;
            float colwidth = (width - (2 * border)) / datalength;
            float halfcol = colwidth / 2;
            float lasth = 0;                
            for (int i = 0; i < values.length; i++) {
                float val = values[i] - min;
                float rat = val / diff;
                float h = graphHeight * rat;
                if (i > 0)
                    canvas.drawLine(((i - 1) * colwidth) + (horStart + 1) + halfcol, (border - lasth) + graphHeight, (i * colwidth) + (horStart + 1) + halfcol, (border - h) + graphHeight, linePaint);
                lasth = h;

我只是不明白为什么一个人比另一个人效率更高。有什么想法吗?

5 个答案:

答案 0 :(得分:2)

CLEAR

在第一部分中,对象{moveTo,lineTo,drawPath和close}有三个操作


在第二部分中,除了对象上的一个操作外,它都是浮动操作

答案 1 :(得分:1)

使用Path s会使绘图明显慢于简单地告诉Canvas在两点之间绘制一条直线,因为Path是一个比drawLine()更复杂的对象{ {1}}使用。 Path也会根据Style中的Paint进行填充和框架处理,这也会导致速度放缓。

通常,在循环中使用对象并调用大量方法会降低代码的速度。

答案 2 :(得分:1)

经过一些搜索后,问题可能来自我说的地方:你应该只为图的第一个点调用moveTo,然后只在循环中调用lineTo。完全定义路径后(在for循环之后),您可以绘制它。路径已针对您的目的进行了优化,但您没有正确使用它。

http://developer.android.com/reference/android/graphics/Path.html#lineTo%28float,%20float%29

答案 3 :(得分:1)

我认为你应该这样做:

float yStart = 300f;

drawPath.moveTo(xStart, yStart);

for (int i=0; i < values.length; i++){              
    drawPath.lineTo(xStart+10, values[i]);
    xStart += 10;
    yStart = values[i]; 
}

drawPath.close();

canvas.drawPath(drawPath, linePaint);

否则你将在画布上画出drawPath X次的“建筑物”。

此外,您可以预先计算路径,并在onDraw中仅使用canvas.drawPath。

答案 4 :(得分:0)

此外,您应该使用path.reset()来清理内存。否则,每次使用相同的路径绘制不同的对象时,它都会绘制您在使用该路径之前绘制的所有对象。所以完整的代码就是。

float yStart = 300f;

drawPath.moveTo(xStart, yStart);

for (int i=0; i < values.length; i++){       
    drawPath.lineTo(xStart+10, values[i]);       
    xStart += 10;       
    yStart = values[i];
}

drawPath.close();

canvas.drawPath(drawPath, linePaint);

drawPath.reset();
相关问题