Почему алгоритм такой медленный? - PullRequest
3 голосов
/ 01 августа 2011

Я создаю линейный график, и код, который я первоначально использовал, был настолько медленным при рисовании, что он был бесполезен. Я заменил его кодом, который нашел в Интернете, и он стал намного быстрее. Мне было просто любопытно, почему оригинальный код такой медленный. Весь приведенный ниже код находится внутри метода 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 ]

2 голосов
/ 01 августа 2011

Это CLEAR

В первом фрагменте есть три операции над объектами {moveTo, lineTo, drawPath и close}


IntВо-вторых, это все операции с плавающей точкой, кроме одной операции над объектами

1 голос
/ 01 августа 2011

Я думаю, вы должны сделать это так:

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.

1 голос
/ 01 августа 2011

После небольшого поиска проблема, вероятно, возникла там, где я сказал: вы должны вызывать moveTo только для первой точки графика, а затем вызывать только lineTo в цикле.Когда путь определен полностью (после цикла for), вы можете нарисовать его.Путь оптимизирован для ваших целей, но вы не используете его правильно.

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

1 голос
/ 01 августа 2011

Использование Path s делает рисование значительно медленнее, чем простое указание Canvas рисовать прямую линию между двумя точками, поскольку Path является гораздо более сложным объектом, чем 2 точки, которые использует drawLine(). Path s также заполнены и оформлены на основе Style в Paint, что также может вызвать замедление.

В общем, использование объектов и вызов большого количества методов в цикле замедляет ваш код.

0 голосов
/ 22 мая 2014

Кроме того, вы должны использовать 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...