2016-06-14 22 views
7

Sto cercando di ottenere statistiche sulle prestazioni su come Android carica, decodifica e rende immagini WebP contro JPG, ma i miei risultati sono un po 'confusi.Prestazioni JPG vs WebP su Android

Decodifica le immagini WebP in Bitmap sono lente rispetto a JPG.

Alcune statistiche:

  • WebP 66% in meno di dimensione del file di JPG, 267% in più di tempo per decodificare.
  • WebP 38% di file in meno rispetto a JPG, 258% in più di tempo per la decodifica.
  • WebP 89% di file in meno rispetto a JPG, 319% in più di tempo per la decodifica.

Qualcuno è a conoscenza di problemi relativi alle prestazioni o perché la decodifica WebP è più difficile di JPG.

Questa è la mia prova:

public class BulkLoadFromDisk implements Runnable { 

    private static final String TAG = "BulkLoadFromDisk"; 

    private static final int TIMES = 10; 

    private final ResourceProvider resourceProvider; 
    private final Activity context; 
    private final int counter; 
    private long averageLoadTimeNano; 
    private long averageConvertTimeNano; 
    private final ImagesFactory.FORMAT format; 
    private final CompleteListener listener; 

    public BulkLoadFromDisk(Activity context, ResourceProvider resourceProvider, 
          CompleteListener listener, ImagesFactory.FORMAT format) { 
     this.resourceProvider = resourceProvider; 
     this.context = context; 
     this.counter = resourceProvider.length(); 
     this.format = format; 
     this.listener = listener; 
    } 

    @Override 
    public void run() { 

     try { 
      Thread.sleep(200); 
     } catch (InterruptedException e) { 
      Log.e(TAG, e.getMessage(), e); 
     } 

     try { 
      String file; 
      long loadBegin, loadEnd; 
      long convertBegin, convertEnd; 
      Bitmap bitmap; Drawable d; 
      String extension = "." + format.name().toLowerCase(); 
      InputStream inputStream; 
      for(int j = 0; j < TIMES; j++) { 

       for(int index = 0; index < counter; index++) { 
        file = resourceProvider.get(index).concat(extension); 
        inputStream = context.getAssets().open(file); 

        // Load bitmap from file 
        loadBegin = System.nanoTime(); 
        bitmap = BitmapFactory.decodeStream(inputStream); 
        assert (bitmap != null); 
        loadEnd = System.nanoTime(); 

        // Convert bitmap to drawable 
        convertBegin = System.nanoTime(); 
        d = new BitmapDrawable(context.getResources(), bitmap); 
        assert (d != null); 
        convertEnd = System.nanoTime(); 

        averageLoadTimeNano += (loadEnd - loadBegin); 
        averageConvertTimeNano += (convertEnd - convertBegin); 
       } 

      } 
      averageLoadTimeNano = averageLoadTimeNano/(TIMES * counter); 
      averageConvertTimeNano = averageConvertTimeNano/(TIMES * counter); 

      if(listener != null && context != null) { 
       context.runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         listener.onComplete(BulkLoadFromDisk.this); 
        } 
       }); 
      } 

     } 
     catch (final IOException e) { 

      if(listener != null && context!= null) { 

       context.runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         listener.onError(e); 
        } 
       }); 

      } 

     } finally { 
      System.gc(); 
     } 

    } 

    public interface CompleteListener { 
     void onComplete(BulkLoadFromDisk task); 
     void onError(Exception e); 
    } 

    public long getAverageLoadTimeNano() { 
     return averageLoadTimeNano; 
    } 

    public long getAverageConvertTimeNano() { 
     return averageConvertTimeNano; 
    } 

    public ImagesFactory.FORMAT getFormat() { 
     return format; 
    } 

    public String resultToString() { 
     final StringBuffer sb = new StringBuffer("BulkLoadFromDisk{"); 
     sb.append("averageLoadTimeNano=").append(Utils.nanosToBest(averageLoadTimeNano).first 
       + Utils.nanosToBest(averageLoadTimeNano).second); 
     sb.append(", averageConvertTimeNano=").append(Utils.nanosToBest(averageConvertTimeNano).first 
       + Utils.nanosToBest(averageConvertTimeNano).second); 
     sb.append(", format=").append(format); 
     sb.append('}'); 
     return sb.toString(); 
    } 
+0

Solo per motivi statistici, se si utilizzano solo 10 ripetizioni, è necessario aumentarlo, ad esempio, a 1000. Quando ho eseguito un test per verificare se '++ i' era più veloce di' i ++ ', l'ho utilizzato una ripetizione di circa 1000000. – luizfzs

risposta

1

So che questa è una vecchia questione e non ho ancora studiato le in-profondità della WebP, ma è probabilmente perché si tratta di un algoritmo più complesso, quindi, il motivo per cui ha rapporti di compressione migliori rispetto a JPEG. WebP è basato sul codec VP8, che è a sua volta un concorrente esente da royalty per il formato h264 ampiamente utilizzato e pesante.

JPEG è ampiamente utilizzato, tuttavia, è un formato veramente vecchio ed è notevolmente più semplice del codec VP8 di WebP.