Saya harus menyinkronkan file besar di beberapa mesin. Ukuran file bisa hingga 6GB. Sinkronisasi akan dilakukan secara manual setiap beberapa minggu. Saya tidak dapat mempertimbangkan nama file karena mereka dapat berubah kapan saja.
Rencana saya adalah membuat checksum pada PC tujuan dan pada PC sumber dan kemudian menyalin semua file dengan checksum, yang belum ada di tujuan, ke tujuan. Upaya pertama saya adalah seperti ini:
using System.IO;
using System.Security.Cryptography;
private static string GetChecksum(string file)
{
using (FileStream stream = File.OpenRead(file))
{
SHA256Managed sha = new SHA256Managed();
byte[] checksum = sha.ComputeHash(stream);
return BitConverter.ToString(checksum).Replace("-", String.Empty);
}
}
Masalahnya adalah runtime:
- dengan SHA256 dengan File 1,6 GB -> 20 menit
- dengan MD5 dengan File 1,6 GB -> 6,15 menit
Apakah ada cara yang lebih baik - lebih cepat - untuk mendapatkan checksum (mungkin dengan fungsi hash yang lebih baik)?
c#
.net
large-files
checksum
krono
sumber
sumber
Jawaban:
Masalahnya di sini adalah yang
SHA256Managed
membaca 4096 byte pada suatu waktu (mewarisi dariFileStream
dan menimpaRead(byte[], int, int)
untuk melihat berapa banyak yang dibaca dari filestream), yang merupakan buffer terlalu kecil untuk disk IO.Untuk mempercepat hal-hal (2 menit untuk hashing berkas 2 Gb pada mesin dengan SHA256, 1 menit untuk MD5) bungkus
FileStream
diBufferedStream
dan set berukuran cukup ukuran buffer (saya mencoba dengan ~ 1 Mb buffer):sumber
Jangan checksum seluruh file, buat checksum setiap 100mb, jadi setiap file memiliki koleksi checksum.
Kemudian ketika membandingkan checksum, Anda dapat berhenti membandingkan setelah checksum berbeda pertama, keluar lebih awal, dan menyelamatkan Anda dari pemrosesan seluruh file.
Masih perlu waktu penuh untuk file yang identik.
sumber
Seperti yang dicatat Anton Gogolev , FileStream secara default membaca 4096 byte, tetapi Anda bisa menentukan nilai lain menggunakan konstruktor FileStream:
Perhatikan bahwa Brad Abrams dari Microsoft menulis pada tahun 2004:
sumber
sumber
Aktifkan port windows dari md5sum.exe . Ini sekitar dua kali lebih cepat dari implementasi .NET (setidaknya pada komputer saya menggunakan file 1,2 GB)
sumber
Oke - terima kasih untuk Anda semua - izinkan saya menyelesaikannya:
sumber
Saya melakukan tes dengan ukuran buffer, menjalankan kode ini
Dan saya menguji dengan file berukuran 29½ GB, hasilnya
Saya menjalankan CPU i5 2500K, ram 12 GB, dan drive SSD OCZ Vertex 4 256 GB.
Jadi saya pikir, bagaimana dengan hard drive 2TB standar. Dan hasilnya seperti ini
Jadi saya akan merekomendasikan tidak ada buffer atau buffer max 1 mill.
sumber
Anda melakukan sesuatu yang salah (mungkin buffer baca terlalu kecil). Pada mesin usia yang tidak senonoh (Athlon 2x1800MP dari 2002) yang memiliki DMA pada disk mungkin rusak (6,6M / s sangat lambat ketika melakukan pembacaan berurutan):
Buat file 1G dengan data "acak":
1m5.299d
1m58.832s
Ini juga aneh, MD5 secara konsisten lebih lambat daripada SHA1 bagi saya (reran beberapa kali).
sumber
Saya tahu bahwa saya terlambat ke pesta tetapi melakukan tes sebelum benar-benar menerapkan solusi.
Saya melakukan tes terhadap kelas MD5 inbuilt dan juga md5sum.exe . Dalam kasus saya, kelas inbuilt mengambil 13 detik di mana md5sum.exe juga sekitar 16-18 detik dalam setiap menjalankan.
sumber
Anda dapat melihat XxHash.Net ( https://github.com/wilhelmliao/xxHash.NET )
Algorythm xxHash tampaknya lebih cepat daripada yang lainnya.
Beberapa patokan di situs xxHash: https://github.com/Cyan4973/xxHash
PS: Saya belum pakai.
sumber