【问题标题】:JPG vs WebP performance on AndroidAndroid 上 JPG 与 WebP 的性能对比
【发布时间】:2016-10-15 05:47:33
【问题描述】:

我正在尝试获取有关 Android 如何针对 JPG 加载、解码和渲染 WebP 图像的性能统计信息,但我的结果有点混乱。

将 WebP 图像解码为位图比 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();
    }

【问题讨论】:

  • 只是为了统计,如果你只使用10次重复,你应该增加它,比如说,到1000。当我做一个测试来检查++i是否比i++快,我用了大约1000000的重复。

标签: java android performance webp


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2016-04-15
    • 2019-10-01
    • 2019-02-14
    • 2019-05-22
    • 1970-01-01
    • 2018-03-14
    • 2013-01-16
    • 2012-03-06
    相关资源
    最近更新 更多