Fast hashing (Spooky, xxH, Farm, Fast) slow?

Viewed 232

I was searching for a faster hashing method for files and streams than MD5 and looked at the fancy Spooky and xxH hash, which should be very fast, but in my tests they are two times slower than MD5, altthough their performace should be up to 30 times faster? The creation of the hashing algo is only done one time, to exclude this time from the hashing time.

public void HashPerformance()
        {
            var filePath = @"C:\Temp\";

            Debug.WriteLine("---MD5---");
            var hashAlgoMD5 = ((HashAlgorithm)CryptoConfig.CreateFromName("MD5"));
            ForeachFile(filePath, (stream) =>
            {
                var hashBytes = hashAlgoMD5.ComputeHash(stream);
                var hashString = BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
            });

            Debug.WriteLine("---SpookyHash---");
            var hashAlgoSpooky = SpookyHashV2Factory.Instance.Create();
            ForeachFile(filePath, (stream) =>
            {
                var hashString = hashAlgoSpooky.ComputeHash(stream).AsHexString();
            });

            Debug.WriteLine("---xxH Hash---");
            var hashAlgoxxH = xxHashFactory.Instance.Create();
            ForeachFile(filePath, (stream) =>
            {
                var hashString = hashAlgoxxH.ComputeHash(stream).AsHexString();
            });

            Debug.WriteLine("---Farm Hash---");
            var hashFarm64 = new FarmHash64();
            ForeachFile(filePath, (stream) =>
            {
                var fileBytes = ReadStreamToArray(stream);
                if (fileBytes.LongLength > 0)
                {
                    var hashBytes = hashFarm64.ComputeHash(fileBytes);
                    var hashString = BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
                }
            });

            Debug.WriteLine("---SharpFarm Hash---");
            ForeachFile(filePath, (stream) =>
            {
                var fileBytes = ReadStreamToArray(stream);
                if (fileBytes.LongLength > 0)
                {
                    var hashNum = Farmhash.Sharp.Farmhash.Hash64(fileBytes, fileBytes.Length);
                    var hashString = hashNum.ToString();
                }
            });

            Debug.WriteLine("---Smash xxH Hash---");
            var algoSmashxxH = Smash.xxHash.Create64(1212);
            ForeachFile(filePath, (stream) =>
            {
                var fileBytes = ReadStreamToArray(stream);
                if (fileBytes.LongLength > 0)
                {
                    algoSmashxxH.Write(fileBytes, 0, fileBytes.Length);
                    var hashNum = algoSmashxxH.Compute();
                    var hashString = hashNum.ToString();
                }
            });
        }

        private static void ForeachFile(string filePath, Action<Stream> action)
        {
            int cnt = 0;
            var watch = new Stopwatch();
            watch.Start();

            Debug.WriteLine("---Start:...---");

            var files = Directory.GetFiles(filePath, "*.*", SearchOption.AllDirectories);
            foreach (var file in files)
            {
                using (var stream = File.OpenRead(file))
                {
                    action(stream);
                }

                cnt++;
            }

            watch.Stop();
            Debug.WriteLine($"---End: Time={watch.Elapsed}, Count={cnt}---");
        }

        public static byte[] ReadStreamToArray(Stream input)
        {
            byte[] buffer = new byte[16 * 1024];
            using (MemoryStream ms = new MemoryStream())
            {
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
                return ms.ToArray();
            }
        }
---MD5---
---Start:...---
---End: Time=00:00:03.5753196, Count=3226---
---SpookyHash---
---Start:...---
---End: Time=00:00:05.7597098, Count=3226---
---xxH Hash---
---Start:...---
---End: Time=00:00:05.8014953, Count=3226---
---Farm Hash---
---Start:...---
---End: Time=00:00:04.6713400, Count=3226---
---SharpFarm Hash---
---Start:...---
---End: Time=00:00:04.2867251, Count=3226---
---Smash xxH Hash---
---Start:...---
---End: Time=00:00:05.5495436, Count=3226---

Is the C# implementation of there hashes so bad, or what I´m doing wrong here?

PS: I´m using the System.Data.HasFunction.SpookyHash / System.Data.HasFunction.xxHash Nuget packages.

Edit: I added FarmHash and FastHash and tested different Nugets, but always the same result.

0 Answers
Related