Zstd: Rasio kompresi lebih baik jika konteks kompresi dibuang secara berkala

Dibuat pada 8 Jul 2019  ·  3Komentar  ·  Sumber: facebook/zstd

Saya secara konsisten mendapatkan rasio kompresi yang sedikit lebih baik jika konteks kompresi tidak digunakan kembali.
Saya membuat konteks kompresi ZSTD, kemudian dalam satu lingkaran memanggil ZSTD_compressCCtx, setiap kali memberikan buffer 1MB dengan data. Di akhir proses, konteks kompresi dibebaskan.
Jika saya membebaskan konteks kompresi dan membuat yang baru sebelum melanjutkan untuk mengompresi buffer 1MB berikutnya, ukuran file keluaran secara konsisten sekitar 1% lebih kecil.
Fakta menarik lainnya adalah rasio kompresi sekitar 1 - 1,5% lebih baik jika saya menggunakan buffer input 2MB dengan data, dibandingkan dengan buffer input 1MB.
Dalam kasus penggunaan saya, saya tidak dibatasi oleh sumber daya memori.
Pertanyaan

  • Apakah praktik yang lebih baik untuk membuang konteks kompresi antara mengompresi potongan data yang besar?

    • Berapa ukuran buffer input optimal yang direkomendasikan (yaitu mengurangi ukuran buffer akan menurunkan rasio kompresi, sedangkan meningkatkan ukuran buffer tidak akan meningkatkan rasio kompresi)?

    • Cara apa pun untuk memberi tahu zstd "gunakan memori sebanyak yang Anda inginkan, tetapi beri saya rasio dan / atau kecepatan kompresi yang lebih baik"

    • Apakah benar-benar kompresi streaming dengan konteks hanya bagus untuk kasus penggunaan dengan memori terbatas? Jika saya memiliki banyak memori, lebih baik saya mengompresi buffer besar (> 1MB) secara independen?

question

Semua 3 komentar

Hai @cherepanh ,

hasil ini mengejutkan.
Menggunakan ZSTD_compressCCtx() , dengan input yang sama dan tingkat kompresi yang sama, tidak masalah (dari perspektif rasio kompresi) apakah konteksnya digunakan kembali atau tidak. Satu-satunya dampak menggunakan kembali konteks adalah menghemat alokasi dan waktu inisialisasi, itu saja. Jika memengaruhi rasio kompresi, itu aneh, dan mungkin salah.

Saya ingin mereproduksi skenario ini jika memungkinkan. Versi mana yang Anda gunakan?

Apakah praktik yang lebih baik untuk membuang konteks kompresi antara mengompresi potongan data yang besar?

Anda tidak perlu membuang konteks.
Satu-satunya alasan yang "baik" adalah untuk menyederhanakan kode.
Tapi dari perspektif kinerja, seharusnya hanya menguntungkan, tidak ada sisi negatifnya.

Apa yang direkomendasikan untuk ukuran buffer input optimal

Ini sangat situasional. Tidak ada ambang batas "universal".
Secara umum, di luar ukuran jendela 8x, meningkatkan ukuran potongan semakin lama semakin tidak berharga.
Ukuran jendela, bagaimanapun, adalah nilai dinamis, tergantung pada tingkat kompresi.
Ini bervariasi dari 512 KB (level 1) hingga 8 MB (level 19).

Cara apa pun untuk memberi tahu zstd "gunakan memori sebanyak yang Anda inginkan, tetapi beri saya rasio kompresi yang lebih baik"

Level 19 seharusnya seperti ini

dan / atau kecepatan "

Level 4 umumnya seperti ini: kompresnya cukup cepat, tetapi menggunakan memori yang sangat besar. Itu yang paling dekat yang bisa saya pikirkan.

Apakah benar-benar kompresi streaming dengan konteks hanya bagus untuk kasus penggunaan dengan memori terbatas? Jika saya memiliki banyak memori, lebih baik saya mengompresi buffer besar (> 1MB) secara independen?

Mengompresi / mendekompresi potongan independen dalam sekali jalan ( ZSTD_compressCCtx() dan ZSTD_decompressDCtx() ) lebih sederhana, dan mungkin seefisien mungkin. Jika Anda bisa melakukannya, itu lebih disukai. Selain itu, mode streaming menambahkan banyak kerumitan. Kompleksitasnya sebagian besar bersifat internal dan tersembunyi, tetapi gagasan utamanya adalah, tidak bisa lebih baik / lebih cepat daripada kompresi atau dekompresi sekali jalan yang langsung.

Terima kasih atas jawaban yang sangat menjelaskan.
Saya menelusuri rasio kompresi yang berbeda ke urutan data saya yang berbeda. Ya, menggunakan kembali konteks vs membuang tidak membuat perbedaan, persis seperti yang Anda katakan. Maaf saya harus lebih berhati-hati dan menyelidiki lebih lanjut sebelum mengajukan pertanyaan.
Komentar Anda sangat jelas dan menjelaskan. Saya pikir itu benar-benar perlu ditambahkan ke dokumen. Terutama bagian tentang perbedaan streaming vs non-streaming - Saya selalu berpikir bahwa streaming lebih efisien, karena Anda dapat membuat kamus dengan lebih baik (meskipun tidak jelas bagaimana Anda mengubah kamus saat data berubah dalam file). Pemahaman yang jelas bahwa streaming hampir sama dengan kompresi "berbasis blok" sangatlah penting. Di sisi lain, streaming mungkin lebih efisien, karena Anda secara otomatis menangani ukuran potongan. Saya menggunakan ukuran potongan 1MB dengan tingkat kompresi default 3, dan sepertinya tidak cukup untuk mendapatkan kompresi yang lebih baik. Dari sudut pandang ini, streaming bisa lebih efisien pada rasio kompresi, karena Anda akan menentukan ukuran chunk dengan lebih optimal. (Apakah ini benar???)

streaming hampir sama dengan kompresi "berbasis blok"

Ini tidak persis "sama".

Jika Anda memotong data masukan menjadi beberapa bagian, dan meneruskannya secara independen ke ZSTD_compressCCtx() , Anda akan mendapatkan beberapa potongan terkompresi independen. Setiap potongan terkompresi adalah _frame_ independen. Mereka dapat didekompresi dalam urutan apa pun, karena setiap bingkai bersifat independen.

Jika Anda mengirim data yang sama ke dalam satu aliran, dengan ZSTD_compressStream() , tanpa pemotongan, Anda akan mendapatkan _single frame_. Secara internal, bingkai dipotong menjadi balok, ya, tapi itu tidak masalah, karena balok tidak berdiri sendiri. Untuk memecahkan kode bagian mana pun dari bingkai, Anda perlu memecahkan kode semuanya dari awal.

Secara teori, bingkai tunggal harus dikompresi lebih baik daripada beberapa bingkai independen. Itu karena memotong data menjadi beberapa bagian independen membuatnya kehilangan beberapa peluang kompresi di awal setiap bagian.
Namun, mode cepat hanyalah kompresor "probabilistik", yang membuat taruhan tergesa-gesa agar bisa berjalan cepat. Tidak semua peluang sama, dan terkadang, memilih satu peluang hanya menutupi peluang yang lebih baik di kemudian hari. Ini sangat spesifik data.
Oleh karena itu, dalam beberapa kasus yang jarang terjadi, mungkin terjadi bahwa memotong data menjadi potongan independen akhirnya menjadi kompetitif dengan aliran tunggal.
Tapi saya tidak akan bertaruh. Dalam kebanyakan kasus, aliran tunggal harus menang, jika hanya dengan sangat sedikit.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

escalade picture escalade  ·  3Komentar

vade picture vade  ·  3Komentar

pjebs picture pjebs  ·  3Komentar

rgdoliveira picture rgdoliveira  ·  3Komentar

icebluey picture icebluey  ·  3Komentar