1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// LzmaBench.cs
2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
3baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing System;
4baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing System.IO;
5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
6baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace SevenZip
7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	/// <summary>
9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	/// LZMA Benchmark
10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	/// </summary>
11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	internal abstract class LzmaBench
12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	{
13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		const UInt32 kAdditionalSize = (6 << 20);
14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		const UInt32 kCompressedAdditionalSize = (1 << 10);
15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		const UInt32 kMaxLzmaPropSize = 10;
16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		class CRandomGenerator
18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt32 A1;
20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt32 A2;
21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public CRandomGenerator() { Init(); }
22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public void Init() { A1 = 362436069; A2 = 521288629; }
23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public UInt32 GetRnd()
24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			{
25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				return
26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) ^
27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)));
28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			}
29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		};
30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		class CBitRandomGenerator
32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			CRandomGenerator RG = new CRandomGenerator();
34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt32 Value;
35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			int NumBits;
36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public void Init()
37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			{
38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				Value = 0;
39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				NumBits = 0;
40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			}
41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public UInt32 GetRnd(int numBits)
42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			{
43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				UInt32 result;
44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				if (NumBits > numBits)
45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				{
46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					result = Value & (((UInt32)1 << numBits) - 1);
47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					Value >>= numBits;
48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					NumBits -= numBits;
49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					return result;
50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				}
51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				numBits -= NumBits;
52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				result = (Value << numBits);
53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				Value = RG.GetRnd();
54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				result |= Value & (((UInt32)1 << numBits) - 1);
55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				Value >>= numBits;
56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				NumBits = 32 - numBits;
57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				return result;
58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			}
59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		};
60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		class CBenchRandomGenerator
62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			CBitRandomGenerator RG = new CBitRandomGenerator();
64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt32 Pos;
65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt32 Rep0;
66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public UInt32 BufferSize;
68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public Byte[] Buffer = null;
69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public CBenchRandomGenerator() { }
71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public void Set(UInt32 bufferSize)
73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			{
74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				Buffer = new Byte[bufferSize];
75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				Pos = 0;
76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				BufferSize = bufferSize;
77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			}
78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt32 GetRndBit() { return RG.GetRnd(1); }
79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt32 GetLogRandBits(int numBits)
80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			{
81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				UInt32 len = RG.GetRnd(numBits);
82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				return RG.GetRnd((int)len);
83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			}
84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt32 GetOffset()
85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			{
86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				if (GetRndBit() == 0)
87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					return GetLogRandBits(4);
88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				return (GetLogRandBits(4) << 10) | RG.GetRnd(10);
89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			}
90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt32 GetLen1() { return RG.GetRnd(1 + (int)RG.GetRnd(2)); }
91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt32 GetLen2() { return RG.GetRnd(2 + (int)RG.GetRnd(2)); }
92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public void Generate()
93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			{
94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				RG.Init();
95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				Rep0 = 1;
96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				while (Pos < BufferSize)
97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				{
98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					if (GetRndBit() == 0 || Pos < 1)
99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync						Buffer[Pos++] = (Byte)RG.GetRnd(8);
100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					else
101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					{
102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync						UInt32 len;
103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync						if (RG.GetRnd(3) == 0)
104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync							len = 1 + GetLen1();
105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync						else
106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync						{
107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync							do
108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync								Rep0 = GetOffset();
109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync							while (Rep0 >= Pos);
110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync							Rep0++;
111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync							len = 2 + GetLen2();
112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync						}
113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync						for (UInt32 i = 0; i < len && Pos < BufferSize; i++, Pos++)
114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync							Buffer[Pos] = Buffer[Pos - Rep0];
115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					}
116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				}
117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			}
118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		};
119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		class CrcOutStream : System.IO.Stream
121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public CRC CRC = new CRC();
123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public void Init() { CRC.Init(); }
124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public UInt32 GetDigest() { return CRC.GetDigest(); }
125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public override bool CanRead { get { return false; } }
127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public override bool CanSeek { get { return false; } }
128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public override bool CanWrite { get { return true; } }
129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public override Int64 Length { get { return 0; } }
130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public override Int64 Position { get { return 0; } set { } }
131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public override void Flush() { }
132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public override long Seek(long offset, SeekOrigin origin) { return 0; }
133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public override void SetLength(long value) { }
134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public override int Read(byte[] buffer, int offset, int count) { return 0; }
135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public override void WriteByte(byte b)
137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			{
138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				CRC.UpdateByte(b);
139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			}
140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public override void Write(byte[] buffer, int offset, int count)
141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			{
142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				CRC.Update(buffer, (uint)offset, (uint)count);
143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			}
144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		};
145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		class CProgressInfo : ICodeProgress
147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public Int64 ApprovedStart;
149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public Int64 InSize;
150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public System.DateTime Time;
151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public void Init() { InSize = 0; }
152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			public void SetProgress(Int64 inSize, Int64 outSize)
153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			{
154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				if (inSize >= ApprovedStart && InSize == 0)
155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				{
156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					Time = DateTime.UtcNow;
157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					InSize = inSize;
158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				}
159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			}
160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		const int kSubBits = 8;
162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		static UInt32 GetLogSize(UInt32 size)
164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			for (int i = kSubBits; i < 32; i++)
166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				for (UInt32 j = 0; j < (1 << kSubBits); j++)
167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					if (size <= (((UInt32)1) << i) + (j << (i - kSubBits)))
168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync						return (UInt32)(i << kSubBits) + j;
169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			return (32 << kSubBits);
170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime)
173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt64 freq = TimeSpan.TicksPerSecond;
175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt64 elTime = elapsedTime;
176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			while (freq > 1000000)
177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			{
178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				freq >>= 1;
179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				elTime >>= 1;
180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			}
181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			if (elTime == 0)
182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				elTime = 1;
183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			return value * freq / elTime;
184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		static UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 elapsedTime, UInt64 size)
187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt64 t = GetLogSize(dictionarySize) - (18 << kSubBits);
189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt64 numCommandsForOne = 1060 + ((t * t * 10) >> (2 * kSubBits));
190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt64 numCommands = (UInt64)(size) * numCommandsForOne;
191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			return MyMultDiv64(numCommands, elapsedTime);
192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		static UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 outSize, UInt64 inSize)
195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt64 numCommands = inSize * 220 + outSize * 20;
197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			return MyMultDiv64(numCommands, elapsedTime);
198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		static UInt64 GetTotalRating(
201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt32 dictionarySize,
202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt64 elapsedTimeEn, UInt64 sizeEn,
203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt64 elapsedTimeDe,
204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt64 inSizeDe, UInt64 outSizeDe)
205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			return (GetCompressRating(dictionarySize, elapsedTimeEn, sizeEn) +
207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2;
208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		static void PrintValue(UInt64 v)
211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			string s = v.ToString();
213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			for (int i = 0; i + s.Length < 6; i++)
214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				System.Console.Write(" ");
215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			System.Console.Write(s);
216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		static void PrintRating(UInt64 rating)
219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			PrintValue(rating / 1000000);
221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			System.Console.Write(" MIPS");
222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		static void PrintResults(
225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt32 dictionarySize,
226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt64 elapsedTime,
227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt64 size,
228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			bool decompressMode, UInt64 secondSize)
229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt64 speed = MyMultDiv64(size, elapsedTime);
231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			PrintValue(speed / 1024);
232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			System.Console.Write(" KB/s  ");
233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt64 rating;
234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			if (decompressMode)
235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				rating = GetDecompressRating(elapsedTime, size, secondSize);
236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			else
237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				rating = GetCompressRating(dictionarySize, elapsedTime, size);
238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			PrintRating(rating);
239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		static public int LzmaBenchmark(Int32 numIterations, UInt32 dictionarySize)
242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		{
243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			if (numIterations <= 0)
244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				return 0;
245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			if (dictionarySize < (1 << 18))
246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			{
247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				System.Console.WriteLine("\nError: dictionary size for benchmark must be >= 19 (512 KB)");
248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				return 1;
249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			}
250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			System.Console.Write("\n       Compressing                Decompressing\n\n");
251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			Compression.LZMA.Encoder encoder = new Compression.LZMA.Encoder();
253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			Compression.LZMA.Decoder decoder = new Compression.LZMA.Decoder();
254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			CoderPropID[] propIDs =
257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			{
258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				CoderPropID.DictionarySize,
259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			};
260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			object[] properties =
261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			{
262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				(Int32)(dictionarySize),
263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			};
264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt32 kBufferSize = dictionarySize + kAdditionalSize;
266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;
267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			encoder.SetCoderProperties(propIDs, properties);
269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			System.IO.MemoryStream propStream = new System.IO.MemoryStream();
270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			encoder.WriteCoderProperties(propStream);
271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			byte[] propArray = propStream.ToArray();
272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			CBenchRandomGenerator rg = new CBenchRandomGenerator();
274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			rg.Set(kBufferSize);
276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			rg.Generate();
277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			CRC crc = new CRC();
278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			crc.Init();
279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			crc.Update(rg.Buffer, 0, rg.BufferSize);
280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			CProgressInfo progressInfo = new CProgressInfo();
282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			progressInfo.ApprovedStart = dictionarySize;
283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt64 totalBenchSize = 0;
285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt64 totalEncodeTime = 0;
286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt64 totalDecodeTime = 0;
287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			UInt64 totalCompressedSize = 0;
288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			MemoryStream inStream = new MemoryStream(rg.Buffer, 0, (int)rg.BufferSize);
290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			MemoryStream compressedStream = new MemoryStream((int)kCompressedBufferSize);
291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			CrcOutStream crcOutStream = new CrcOutStream();
292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			for (Int32 i = 0; i < numIterations; i++)
293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			{
294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				progressInfo.Init();
295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				inStream.Seek(0, SeekOrigin.Begin);
296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				compressedStream.Seek(0, SeekOrigin.Begin);
297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				encoder.Code(inStream, compressedStream, -1, -1, progressInfo);
298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				TimeSpan sp2 = DateTime.UtcNow - progressInfo.Time;
299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				UInt64 encodeTime = (UInt64)sp2.Ticks;
300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				long compressedSize = compressedStream.Position;
302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				if (progressInfo.InSize == 0)
303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					throw (new Exception("Internal ERROR 1282"));
304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				UInt64 decodeTime = 0;
306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				for (int j = 0; j < 2; j++)
307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				{
308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					compressedStream.Seek(0, SeekOrigin.Begin);
309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					crcOutStream.Init();
310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					decoder.SetDecoderProperties(propArray);
312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					UInt64 outSize = kBufferSize;
313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					System.DateTime startTime = DateTime.UtcNow;
314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					decoder.Code(compressedStream, crcOutStream, 0, (Int64)outSize, null);
315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					TimeSpan sp = (DateTime.UtcNow - startTime);
316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					decodeTime = (ulong)sp.Ticks;
317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					if (crcOutStream.GetDigest() != crc.GetDigest())
318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync						throw (new Exception("CRC Error"));
319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				}
320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				UInt64 benchSize = kBufferSize - (UInt64)progressInfo.InSize;
321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				PrintResults(dictionarySize, encodeTime, benchSize, false, 0);
322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				System.Console.Write("     ");
323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				PrintResults(dictionarySize, decodeTime, kBufferSize, true, (ulong)compressedSize);
324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				System.Console.WriteLine();
325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				totalBenchSize += benchSize;
327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				totalEncodeTime += encodeTime;
328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				totalDecodeTime += decodeTime;
329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync				totalCompressedSize += (ulong)compressedSize;
330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			}
331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			System.Console.WriteLine("---------------------------------------------------");
332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			PrintResults(dictionarySize, totalEncodeTime, totalBenchSize, false, 0);
333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			System.Console.Write("     ");
334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			PrintResults(dictionarySize, totalDecodeTime,
335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync					kBufferSize * (UInt64)numIterations, true, totalCompressedSize);
336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			System.Console.WriteLine("    Average");
337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync			return 0;
338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync		}
339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync	}
340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
341