Android上的JPG vs WebP性能

时间:2016-06-14 13:06:22

标签: java android performance webp

我试图获取关于Android如何针对JPG加载,解码和渲染WebP图像的性能统计数据,但我的结果有点混乱。

将WebP图像解码为Bitmap比JPG慢。

一些统计数据:

  • WebP文件大小比JPG少66%,解码时间增加267%。
  • WebP文件大小比JPG少38%,解码时间增加258%。
  • WebP文件大小比JPG少89%,解码时间增加319%。

有人知道有关性能的任何问题,或者为什么WebP解码比JPG更难。

这是我的测试:

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();
    }

1 个答案:

答案 0 :(得分:1)

我知道这是一个老问题,我还没有研究过WebP的深入,但可能是因为它是一个更复杂的算法,因此它具有比JPEG更好的压缩率。 WebP基于VP8编解码器,它本身就是广泛使用的重型h264格式的免版税竞争对手。

JPEG被广泛使用,但它是一种非常古老的格式,并且比WebP的VP8编解码器简单得多。