Производительность JPG и WebP на Android

Я пытаюсь получить статистику производительности о том, как Android загружает, декодирует и отображает изображения WebP по сравнению с JPG, но мои результаты немного запутаны.

Декодирование изображений WebP в Bitmap происходит медленнее, чем JPG.

Немного статистики:

  • Размер файла WebP на 66 % меньше, чем у JPG, и на 267 % больше времени на декодирование.
  • WebP на 38 % меньше размера файла, чем JPG, и на 258 % больше времени на декодирование.
  • Размер файла WebP на 89 % меньше, чем у JPG, и на 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();
    }

person Roman    schedule 14.06.2016    source источник
comment
Просто ради статистики, если вы используете только 10 повторений, вы должны увеличить его, скажем, до 1000. Когда я делал тест, чтобы проверить, быстрее ли ++i, чем i++, я использовал повторение около 1000000.   -  person luizfzs    schedule 26.05.2017


Ответы (1)


Я знаю, что это старый вопрос, и я еще не изучил все аспекты WebP, но, вероятно, это потому, что это более сложный алгоритм, поэтому он имеет лучшие коэффициенты сжатия, чем JPEG. WebP основан на кодеке VP8, который сам по себе является бесплатным конкурентом широко используемого и тяжелого формата h264.

JPEG широко используется, однако это действительно старый формат, который значительно проще, чем кодек VP8 WebP.

person Allan Araújo    schedule 30.06.2017