Advertisement
yallie

C# compression algorithms benchmark

Jun 28th, 2011
710
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.48 KB | None | 0 0
  1. //--------------------------------------------------------------------------------------------
  2. // C# compression algorithms benchmark:
  3. //
  4. // * C# LZF: http://csharplzfcompression.codeplex.com
  5. // * QuickLZ 1.5.0 final: http://quicklz.com
  6. // * DeflateStream: http://msdn.microsoft.com/library/system.io.compression.deflatestream.aspx
  7. //
  8. // Written Jun 28, 2011 by yallie@yandex.ru
  9. //--------------------------------------------------------------------------------------------
  10.  
  11. // csc.exe bench.cs LZF.cs QuickLZ.cs
  12.  
  13. using System;
  14. using System.IO;
  15. using System.IO.Compression;
  16. using System.Collections.Generic;
  17. using System.Linq;
  18. using System.Text;
  19. using System.Text.RegularExpressions;
  20. using System.Diagnostics;
  21. using System.Management;
  22. using Lzf;
  23.  
  24. class Program
  25. {
  26.     const int iterations = 5000;
  27.     const int seed = 1234;
  28.  
  29.     static void Main()
  30.     {
  31.         SystemInfo.DisplaySysInfo();
  32.         Console.WriteLine("Generating test data...");
  33.  
  34.         var sample1 = GenerateBinaryData(new Random(seed));
  35.         Console.WriteLine("Binary: {0} bytes.", sample1.Length);
  36.  
  37.         var sample2 = GenerateTextualData(new Random(seed));
  38.         Console.WriteLine("Textual: {0} bytes.", sample2.Length);
  39.  
  40.         var sample3 = GenerateUncompressibleData(new Random(seed));
  41.         Console.WriteLine("Uncompressible: {0} bytes.", sample3.Length);
  42.  
  43.         // save files for reference
  44.         File.WriteAllBytes("bench1.dat", sample1);
  45.         File.WriteAllBytes("bench2.dat", sample2);
  46.         File.WriteAllBytes("bench3.dat", sample3);
  47.  
  48.         Console.WriteLine();
  49.  
  50.         // save compressed data and measure speed
  51.         Benchmark("LZF, binary data", iterations, sample1, "bench1.lzf", LzfCompress, LzfDecompress);
  52.         Benchmark("QuickLZ, binary data", iterations, sample1, "bench1.qlz", QuickLZCompress, QuickLZDecompress);
  53.         Benchmark("DeflateStream, binary data", iterations, sample1, "bench1.dfl", DeflateStreamCompress, DeflateStreamDecompress);
  54.  
  55.         Benchmark("LZF, textual data", iterations, sample2, "bench2.lzf", LzfCompress, LzfDecompress);
  56.         Benchmark("QuickLZ, textual data", iterations, sample2, "bench2.qlz", QuickLZCompress, QuickLZDecompress);
  57.         Benchmark("DeflateStream, textual data", iterations, sample2, "bench2.dfl", DeflateStreamCompress, DeflateStreamDecompress);
  58.  
  59.         Benchmark("LZF, uncompressible data", iterations, sample3, "bench3.lzf", LzfCompress, LzfDecompress);
  60.         Benchmark("QuickLZ, uncompressible data", iterations, sample3, "bench3.qlz", QuickLZCompress, QuickLZDecompress);
  61.         Benchmark("DeflateStream, uncompressible data", iterations, sample3, "bench3.dfl", DeflateStreamCompress, DeflateStreamDecompress);
  62.     }
  63.  
  64.     static void Benchmark(string name, int iterations, byte[] inputData, string outFileName, Func<byte[], CompressionResult> compress, Func<CompressionResult, int> decompress)
  65.     {
  66.         Console.WriteLine("Benchmark name: {0}", name);
  67.  
  68.         var sw = new Stopwatch();
  69.         sw.Start();
  70.         var data = new CompressionResult();
  71.  
  72.         for (var i = 0; i < iterations; i++)
  73.             data = compress(inputData);
  74.  
  75.         sw.Stop();
  76.         data.Save(outFileName);
  77.  
  78.         var speed = iterations * inputData.Length / (sw.Elapsed.TotalMilliseconds > 0 ? sw.Elapsed.TotalMilliseconds : 1) / 1000;
  79.         Console.WriteLine("Compression:    size: {1,6} -> {2,6}, elapsed: {3}, speed: {4:#0.000} mb/s", name, inputData.Length, data.Length, sw.Elapsed, speed);
  80.  
  81.         sw = new Stopwatch();
  82.         sw.Start();
  83.         var length = 0;
  84.  
  85.         for (var i = 0; i < iterations; i++)
  86.             length = decompress(data);
  87.  
  88.         sw.Stop();
  89.  
  90.         speed = iterations * data.Length / (sw.Elapsed.TotalMilliseconds > 0 ? sw.Elapsed.TotalMilliseconds : 1) / 1000;
  91.         Console.WriteLine("Decompression:  size: {1,6} -> {2,6}, elapsed: {3}, speed: {4:#0.000} mb/s", name, data.Length, length, sw.Elapsed, speed);
  92.         Console.WriteLine();   
  93.     }
  94.  
  95.     class CompressionResult
  96.     {
  97.         public byte[] Data { get; set; }
  98.  
  99.         public int Length { get; set; }
  100.  
  101.         public int SourceLength { get; set; }
  102.  
  103.         public void Save(string fileName)
  104.         {
  105.             using (var fs = File.Create(fileName))
  106.             {
  107.                 fs.Write(Data, 0, Length);
  108.                 fs.Close();
  109.             }
  110.         }
  111.     }
  112.  
  113.     static LZF lzf = new LZF();
  114.  
  115.     static CompressionResult LzfCompress(byte[] data)
  116.     {
  117.         var output = new byte[data.Length * 2];
  118.         var size = lzf.Compress(data, data.Length, output, output.Length);
  119.         return new CompressionResult
  120.         {
  121.             Data = output,
  122.             Length = size,
  123.             SourceLength = data.Length
  124.         };
  125.     }
  126.  
  127.     static int LzfDecompress(CompressionResult data)
  128.     {
  129.         var output = new byte[data.Length * 2];
  130.         return lzf.Decompress(data.Data, data.Length, output, output.Length);
  131.     }
  132.  
  133.     static CompressionResult QuickLZCompress(byte[] data)
  134.     {
  135.         var output = QuickLZ.compress(data, 1);
  136.         return new CompressionResult
  137.         {
  138.             Data = output,
  139.             Length = output.Length,
  140.             SourceLength = data.Length
  141.         };
  142.     }
  143.  
  144.     static int QuickLZDecompress(CompressionResult data)
  145.     {
  146.         var output = QuickLZ.decompress(data.Data);
  147.         return output.Length;
  148.     }
  149.  
  150.     static CompressionResult DeflateStreamCompress(byte[] data)
  151.     {
  152.         using (var output = new MemoryStream())
  153.         using (var ds = new DeflateStream(output, CompressionMode.Compress))
  154.         {
  155.             ds.Write(data, 0, data.Length);
  156.             ds.Close();
  157.  
  158.             var outData = output.ToArray();
  159.             return new CompressionResult
  160.             {
  161.                 Data = outData,
  162.                 Length = outData.Length,
  163.                 SourceLength = data.Length
  164.             };
  165.         }
  166.     }
  167.  
  168.     static int DeflateStreamDecompress(CompressionResult data)
  169.     {
  170.         using (var input = new MemoryStream(data.Data))
  171.         using (var ds = new DeflateStream(input, CompressionMode.Decompress))
  172.         {
  173.             var br = new BinaryReader(ds);
  174.             var output = br.ReadBytes(data.SourceLength + 100);
  175.             return output.Length;
  176.         }
  177.     }
  178.  
  179.     static byte[] GenerateBinaryData(Random rnd)
  180.     {
  181.         return GenerateData(rnd, 20000, 30, 0, Byte.MaxValue);
  182.     }
  183.  
  184.     static byte[] GenerateTextualData(Random rnd)
  185.     {
  186.         return Encoding.Default.GetBytes(new MarkovChainGenerator().Generate(rnd, 100000));
  187.     }
  188.  
  189.     static byte[] GenerateUncompressibleData(Random rnd)
  190.     {
  191.         return GenerateData(rnd, 200000, 2, 0, Byte.MaxValue);
  192.     }
  193.  
  194.     static byte[] GenerateData(Random rnd, int iterations, int maxRepeats, byte min, byte max)
  195.     {
  196.         var result = new List<byte>();
  197.  
  198.         for (var i = 0; i < iterations; i++)
  199.         {
  200.             var c = min + rnd.Next(max);
  201.  
  202.             for (var j = 0; j < rnd.Next(maxRepeats); j++)
  203.                 result.Add((byte)c);
  204.         }
  205.        
  206.         return result.ToArray();
  207.     }
  208.  
  209.     // Thanks to Visar Shehu for an easy Markov chain example code:
  210.     // http://phalanx.spartansoft.org/2010/03/30/markov-chain-generator-in-c/
  211.     class MarkovChainGenerator
  212.     {
  213.         class MarkovChain
  214.         {
  215.             public char Letter { get; set; }
  216.  
  217.             public List<char> Chain { get; set; }
  218.  
  219.             public static string // some pseudo-english text generated from Christmas Carol by Charles Dickens
  220.                 Sample = @"enbere, vers i ther to y bro the gence, and or eep t tur theavin lover ppearised of die?`
  221.                 `th `a maden mive one s yould be led thy, by thite, whorteror tay use ting, and bled pheart per a ll,
  222.                 had he s saits h airoad is t or up hed at hith` saittle wome nenbermer of and th, it moiceso rundrept
  223.                 ttle the scrow!` was knowithdvancheers tore humbuch ful r abojecte and sll than be to be to hat ht ha
  224.                 verades, thich and by t he a non. ` `doke unfas, re wasaid eleciden air a d in steand s, wheir for up
  225.                 were, butributenburyiced fielowed dond with aid, fros so hear donistrupte of foug usutsethat overy bry
  226.                 tour d pull mays the causearthe sanothis stmas exand, to d, hather wouch gnitil thow ws of gled thing `
  227.                 is wheriarssocid sck hing,` `hey's, colow hin; feas car he `even sundress ccepting to ympatartlk-er;
  228.                 for, wento man yo man oldistrson do n ther obe aber irits is his mrs. somet; orsost he un, an't sclais
  229.                 fable havendin wit.` `why doorooge thoment as the had to th here ile oined in genily us ma".Replace("`", "\"");
  230.         }
  231.  
  232.         List<MarkovChain> chains = new List<MarkovChain>();
  233.  
  234.         public MarkovChainGenerator()
  235.         {
  236.             Train(MarkovChain.Sample, 4);
  237.         }
  238.  
  239.         public void Train(String text, int level)
  240.         {
  241.             text = Regex.Replace(text, @"\s+", " ").ToLower();
  242.  
  243.             for (var i = 0; i < text.Length - level - 1; i++)
  244.             {
  245.                 var c = text[i];
  246.                 var chain = new List<char>();
  247.    
  248.             for (var j = 0; j < level; j++)
  249.                 chain.Add(text[j + i + 1]);
  250.  
  251.                 chains.Add(new MarkovChain
  252.                 {
  253.                     Letter = c,
  254.                     Chain = chain
  255.                 });
  256.             }
  257.         }
  258.  
  259.         public string Generate(Random rnd, int numChars)
  260.         {
  261.             var sb = new StringBuilder();
  262.             var index = rnd.Next(chains.Count);
  263.             var startChar = chains[index].Letter;
  264.  
  265.             while (sb.Length < numChars)
  266.             {
  267.                 var list = chains.Where(c => c.Letter == startChar).ToList();
  268.                 var rndChain = list[rnd.Next(list.Count)];
  269.  
  270.                 foreach (char c in rndChain.Chain)
  271.                 {
  272.                     sb.Append(c);
  273.                     startChar = c;
  274.                 }
  275.             }
  276.  
  277.             return sb.ToString();
  278.         }
  279.     }
  280.  
  281.     public class SystemInfo
  282.     {
  283.         public string CpuName { get; private set; }
  284.  
  285.         public string OperatingSystem { get { return Environment.OSVersion.VersionString; } }
  286.  
  287.         public bool Is64Bit { get { return Environment.Is64BitProcess; } }
  288.  
  289.         public SystemInfo()
  290.         {
  291.             var searcher = new ManagementObjectSearcher("select * from Win32_Processor");
  292.             foreach (ManagementObject mo in searcher.Get())
  293.             {
  294.                 CpuName = Regex.Replace(mo["Name"].ToString(), @"\s+", " ").Trim();
  295.                 break;
  296.             }
  297.         }
  298.  
  299.         public static void DisplaySysInfo()
  300.         {
  301.             var si = new SystemInfo();
  302.             Console.WriteLine("Cpu: {0}", si.CpuName);
  303.             Console.WriteLine("Operating System: {0}", si.OperatingSystem);
  304.             Console.WriteLine("Running in 64-bit process: {0}", si.Is64Bit ? "yes" : "no");
  305.             Console.WriteLine();
  306.         }
  307.     }
  308. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement