开发者

canvas.drawText - many times vs. once overhead

开发者 https://www.devze.com 2023-02-25 17:35 出处:网络
Is there a significant difference between calling drawText once on an entire string vs. calling drawText for ea开发者_运维技巧ch character (or word) in the string?For fun, I put a test together for th

Is there a significant difference between calling drawText once on an entire string vs. calling drawText for ea开发者_运维技巧ch character (or word) in the string?


For fun, I put a test together for this. I had assumed that the full string draw would be faster mostly due to a reduced number of context switches from java to native code. The results were interesting.

The test is as follows. I created a simple custom view that extends View and implements onDraw as follows:

String text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String t[] = {"A","B","C","D","E","F","G","H","I","J",
              "K","L","M","N","O","P","Q","R","S","T",
              "U","V","W","X","Y","Z"};
long fulltime=0;
double fullavetime=0;
long fullcount=0;   
long chartime=0;
double charavetime=0;
long charcount=0;
@Override
protected void onDraw(Canvas canvas) {
    float width = (float) getWidth();
    float inc=width/26;
    float y1 = (float) getHeight() / 3;
    float y2 = y1*2;;
    float x=0;

        // do this test loop 1000 times to get time data
    if (fullcount < 1000) {

        // test by char using a simple 26 char string
        // I tried to eliminate as much overhead as possible
        // so this just pulls strings from an array and draws them
    long start=System.currentTimeMillis();

    for (int i=0;i<26;i++) {
        canvas.drawText(t[i], x, y1, textPaint);
        x+=inc;
    }

    long end=System.currentTimeMillis();
    long elapse=end-start;
    chartime+=elapse;
    charcount++;
    charavetime=(double)chartime/charcount;

        // draw the entire 26 char string at once
    x=0f;
    start=System.currentTimeMillis();

    canvas.drawText(text, x, y2, textPaint);

    end=System.currentTimeMillis();
    elapse=end-start;
    fulltime+=elapse;
    fullcount++;
    fullavetime=(double)fulltime/fullcount;
    } else {
           // after the 1000 test draws, just paint the results on screen
        canvas.drawText("bychar "+charavetime, 0, y1, textPaint);
        canvas.drawText("  full "+fullavetime, 0, y2, textPaint);
    }
        // keep painting over and over
    invalidate();
}

I ran this on three phones I have handy, here are the results

HTC EVO 4G (2.2)
bychar 1.055  1.142  1.184
full    .398   .354   .432

Motorola Droid (2.1 up 1)
bychar .951  1.108  1.071
full   .138   .146   .134

Nexus One (2.3.3)
bychar .991 1.033 1.045 .938
full   .839  .886  .891 .819

I also did the emulator which was comically skewed with bychar results 10x full string results.

The results have some surprises. Clearly the motorola droid has a really fast native text painting routine and equally slow java to native thunks.

As always, double check the code, I may have done something that skews the test.

My take away is that you should draw full strings where possible. You mileage, as they say, may vary.


calling drawtext on each character in a string can lead to misalignment for different devices and screen sizes.

if you write the code to overcome that issue, i would assume at that time you would be keeping track of many more variables and have calls to outside classes and methods, which would slow down the ondraw of the canvas. (it slows down canvas if canvas has to do calculations mid-draw or call outside classes, etc)

Since ondraw is an inherited method of canvas, it shouldnt have much of an inpact if you use multiple instances. its all the coding behind it that would slow it down

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号