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