简体   繁体   中英

Improving for-each performance

I have the following CountDownTimer running constantly at my Android Application.

CountDownTimer timer_status;
timer_status = new CountDownTimer(1000,1000) {

    List<Integer> lst = new ArrayList<Integer>();
    int k=0;
    @Override
    public void onTick(long millisUntilFinished) {


        String S = "";
        k=0;
        byte[] writeBuffer = new byte[8];

        for (int value : lst) {

            if(k==8) {
                k=0;
                S="";
             }

            S = S + String.format("%02x ", value).toUpperCase();
            writeBuffer[k] = (byte) value;
            k++;

        }

        editSent.setText(S);                            
}

Every loop, the application creates a new byte[] buffer from a List of Integers.

It work's fine, but is generating GC_FOR_ALLOC at LogCat.

03-05 11:12:41.330: D/dalvikvm(21178): GC_FOR_ALLOC freed 511K, 19% free 4662K/5720K, paused 14ms, total 14ms
03-05 11:12:42.250: D/dalvikvm(21178): GC_FOR_ALLOC freed 511K, 19% free 4662K/5720K, paused 15ms, total 15ms

GC_FOR_ALLOC is triggered because there wasn't enough memory left on the heap to perform an allocation. Might be triggered when new objects are being created.

How can I improve this foreach loop leaving enough memory on the heap?

 StringBuilder sb = new StringBuilder(); 
 k=0; 
 byte[] writeBuffer = new byte[8];

 for (int value : lst) { 
 if(k==8) { k=0; sb.setLength(0); 
 } 
 sb.append(String.format("%02x ", value)); 

 writeBuffer[k] = (byte) value; k++; 
 }

 editSent.setText(sb.toString().toUpperCase());

Apart from StringBuilder , I would like to point out that normal for has better performances than foreach in Android because the foreach loop creates a hidden Iterator object. So avoid using for-each in performance critical code in Android.

Also, if possible use normal Array for primitive types rather than ArrayList as autoboxing/unboxing would take place in each loop which would affect your performance.

Using a StringBuilder is the one thing (see comment).

You can also avoid the local variables S and writeBuffer and use class variables instead, which effectively reuses both with each call instead of passing them to the garbage collection.

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