compress_test.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. package huff0
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io/ioutil"
  6. "math/rand"
  7. "path/filepath"
  8. "strings"
  9. "testing"
  10. "github.com/klauspost/compress/flate"
  11. "github.com/klauspost/compress/zip"
  12. )
  13. type inputFn func() ([]byte, error)
  14. var testfiles = []struct {
  15. name string
  16. fn inputFn
  17. err1X error
  18. err4X error
  19. }{
  20. // Digits is the digits of the irrational number e. Its decimal representation
  21. // does not repeat, but there are only 10 possible digits, so it should be
  22. // reasonably compressible.
  23. {name: "digits", fn: func() ([]byte, error) { return ioutil.ReadFile("../testdata/e.txt") }},
  24. // gettysburg.txt is a small plain text.
  25. {name: "gettysburg", fn: func() ([]byte, error) { return ioutil.ReadFile("../testdata/gettysburg.txt") }},
  26. // Twain is Project Gutenberg's edition of Mark Twain's classic English novel.
  27. {name: "twain", fn: func() ([]byte, error) { return ioutil.ReadFile("../testdata/Mark.Twain-Tom.Sawyer.txt") }},
  28. // Random bytes
  29. {name: "random", fn: func() ([]byte, error) { return ioutil.ReadFile("../testdata/sharnd.out") }, err1X: ErrIncompressible, err4X: ErrIncompressible},
  30. // Low entropy
  31. {name: "low-ent.10k", fn: func() ([]byte, error) { return []byte(strings.Repeat("1221", 10000)), nil }},
  32. // Super Low entropy
  33. {name: "superlow-ent-10k", fn: func() ([]byte, error) { return []byte(strings.Repeat("1", 10000) + strings.Repeat("2", 500)), nil }},
  34. // Zero bytes
  35. {name: "zeroes", fn: func() ([]byte, error) { return make([]byte, 10000), nil }, err1X: ErrUseRLE, err4X: ErrUseRLE},
  36. {name: "crash1", fn: func() ([]byte, error) { return ioutil.ReadFile("../testdata/crash1.bin") }, err1X: ErrIncompressible, err4X: ErrIncompressible},
  37. {name: "crash2", fn: func() ([]byte, error) { return ioutil.ReadFile("../testdata/crash2.bin") }, err4X: ErrIncompressible},
  38. {name: "crash3", fn: func() ([]byte, error) { return ioutil.ReadFile("../testdata/crash3.bin") }, err1X: ErrIncompressible, err4X: ErrIncompressible},
  39. {name: "endzerobits", fn: func() ([]byte, error) { return ioutil.ReadFile("../testdata/endzerobits.bin") }, err1X: nil, err4X: ErrIncompressible},
  40. {name: "endnonzero", fn: func() ([]byte, error) { return ioutil.ReadFile("../testdata/endnonzero.bin") }, err4X: ErrIncompressible},
  41. {name: "case1", fn: func() ([]byte, error) { return ioutil.ReadFile("../testdata/case1.bin") }, err1X: nil},
  42. {name: "case2", fn: func() ([]byte, error) { return ioutil.ReadFile("../testdata/case2.bin") }, err1X: nil},
  43. {name: "case3", fn: func() ([]byte, error) { return ioutil.ReadFile("../testdata/case3.bin") }, err1X: nil},
  44. {name: "pngdata.001", fn: func() ([]byte, error) { return ioutil.ReadFile("../testdata/pngdata.bin") }, err1X: nil},
  45. {name: "normcount2", fn: func() ([]byte, error) { return ioutil.ReadFile("../testdata/normcount2.bin") }, err1X: nil},
  46. }
  47. type fuzzInput struct {
  48. name string
  49. fn inputFn
  50. }
  51. // testfilesExtended is used for regression testing the decoder.
  52. // These files are expected to fail, but not crash
  53. var testfilesExtended []fuzzInput
  54. func init() {
  55. data, err := ioutil.ReadFile("testdata/regression.zip")
  56. if err != nil {
  57. panic(err)
  58. }
  59. zr, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
  60. if err != nil {
  61. panic(err)
  62. }
  63. for _, tt := range zr.File {
  64. if tt.UncompressedSize64 == 0 {
  65. continue
  66. }
  67. rc, err := tt.Open()
  68. if err != nil {
  69. panic(err)
  70. }
  71. b, err := ioutil.ReadAll(rc)
  72. if err != nil {
  73. panic(err)
  74. }
  75. testfilesExtended = append(testfilesExtended, fuzzInput{
  76. name: filepath.Base(tt.Name),
  77. fn: func() ([]byte, error) {
  78. return b, nil
  79. },
  80. })
  81. }
  82. }
  83. func TestCompressRegression(t *testing.T) {
  84. // Match the fuzz function
  85. var testInput = func(data []byte) int {
  86. var enc Scratch
  87. enc.WantLogLess = 5
  88. comp, _, err := Compress1X(data, &enc)
  89. if err == ErrIncompressible || err == ErrUseRLE || err == ErrTooBig {
  90. return 0
  91. }
  92. if err != nil {
  93. panic(err)
  94. }
  95. if len(comp) >= len(data)-len(data)>>enc.WantLogLess {
  96. panic(fmt.Errorf("too large output provided. got %d, but should be < %d", len(comp), len(data)-len(data)>>enc.WantLogLess))
  97. }
  98. dec, remain, err := ReadTable(comp, nil)
  99. if err != nil {
  100. panic(err)
  101. }
  102. out, err := dec.Decompress1X(remain)
  103. if err != nil {
  104. panic(err)
  105. }
  106. if !bytes.Equal(out, data) {
  107. panic("decompression 1x mismatch")
  108. }
  109. // Reuse as 4X
  110. enc.Reuse = ReusePolicyAllow
  111. comp, reUsed, err := Compress4X(data, &enc)
  112. if err == ErrIncompressible || err == ErrUseRLE || err == ErrTooBig {
  113. return 0
  114. }
  115. if err != nil {
  116. panic(err)
  117. }
  118. if len(comp) >= len(data)-len(data)>>enc.WantLogLess {
  119. panic(fmt.Errorf("too large output provided. got %d, but should be < %d", len(comp), len(data)-len(data)>>enc.WantLogLess))
  120. }
  121. remain = comp
  122. if !reUsed {
  123. dec, remain, err = ReadTable(comp, dec)
  124. if err != nil {
  125. panic(err)
  126. }
  127. }
  128. out, err = dec.Decompress4X(remain, len(data))
  129. if err != nil {
  130. panic(err)
  131. }
  132. if !bytes.Equal(out, data) {
  133. panic("decompression 4x with reuse mismatch")
  134. }
  135. enc.Reuse = ReusePolicyNone
  136. comp, reUsed, err = Compress4X(data, &enc)
  137. if err == ErrIncompressible || err == ErrUseRLE || err == ErrTooBig {
  138. return 0
  139. }
  140. if err != nil {
  141. panic(err)
  142. }
  143. if reUsed {
  144. panic("reused when asked not to")
  145. }
  146. if len(comp) >= len(data)-len(data)>>enc.WantLogLess {
  147. panic(fmt.Errorf("too large output provided. got %d, but should be < %d", len(comp), len(data)-len(data)>>enc.WantLogLess))
  148. }
  149. dec, remain, err = ReadTable(comp, dec)
  150. if err != nil {
  151. panic(err)
  152. }
  153. out, err = dec.Decompress4X(remain, len(data))
  154. if err != nil {
  155. panic(err)
  156. }
  157. if !bytes.Equal(out, data) {
  158. panic("decompression 4x mismatch")
  159. }
  160. // Reuse as 1X
  161. dec.Reuse = ReusePolicyAllow
  162. comp, reUsed, err = Compress1X(data, &enc)
  163. if err == ErrIncompressible || err == ErrUseRLE || err == ErrTooBig {
  164. return 0
  165. }
  166. if err != nil {
  167. panic(err)
  168. }
  169. if len(comp) >= len(data)-len(data)>>enc.WantLogLess {
  170. panic(fmt.Errorf("too large output provided. got %d, but should be < %d", len(comp), len(data)-len(data)>>enc.WantLogLess))
  171. }
  172. remain = comp
  173. if !reUsed {
  174. dec, remain, err = ReadTable(comp, dec)
  175. if err != nil {
  176. panic(err)
  177. }
  178. }
  179. out, err = dec.Decompress1X(remain)
  180. if err != nil {
  181. panic(err)
  182. }
  183. if !bytes.Equal(out, data) {
  184. panic("decompression 1x with reuse mismatch")
  185. }
  186. return 1
  187. }
  188. for _, test := range testfiles {
  189. t.Run(test.name, func(t *testing.T) {
  190. buf0, err := test.fn()
  191. if err != nil {
  192. t.Fatal(err)
  193. }
  194. testInput(buf0)
  195. })
  196. }
  197. for _, test := range testfilesExtended {
  198. t.Run(test.name, func(t *testing.T) {
  199. buf0, err := test.fn()
  200. if err != nil {
  201. t.Fatal(err)
  202. }
  203. testInput(buf0)
  204. })
  205. }
  206. }
  207. func TestCompress1X(t *testing.T) {
  208. for _, test := range testfiles {
  209. t.Run(test.name, func(t *testing.T) {
  210. var s Scratch
  211. buf0, err := test.fn()
  212. if err != nil {
  213. t.Fatal(err)
  214. }
  215. if len(buf0) > BlockSizeMax {
  216. buf0 = buf0[:BlockSizeMax]
  217. }
  218. b, re, err := Compress1X(buf0, &s)
  219. if err != test.err1X {
  220. t.Errorf("want error %v (%T), got %v (%T)", test.err1X, test.err1X, err, err)
  221. }
  222. if err != nil {
  223. t.Log(test.name, err.Error())
  224. return
  225. }
  226. if b == nil {
  227. t.Error("got no output")
  228. return
  229. }
  230. min := s.minSize(len(buf0))
  231. if len(s.OutData) < min {
  232. t.Errorf("output data length (%d) below shannon limit (%d)", len(s.OutData), min)
  233. }
  234. if len(s.OutTable) == 0 {
  235. t.Error("got no table definition")
  236. }
  237. if re {
  238. t.Error("claimed to have re-used.")
  239. }
  240. if len(s.OutData) == 0 {
  241. t.Error("got no data output")
  242. }
  243. t.Logf("%s: %d -> %d bytes (%.2f:1) re:%t (table: %d bytes)", test.name, len(buf0), len(b), float64(len(buf0))/float64(len(b)), re, len(s.OutTable))
  244. s.Out = nil
  245. bRe, _, err := Compress1X(b, &s)
  246. if err == nil {
  247. t.Log("Could re-compress to", len(bRe))
  248. }
  249. })
  250. }
  251. }
  252. func TestCompress4X(t *testing.T) {
  253. for _, test := range testfiles {
  254. t.Run(test.name, func(t *testing.T) {
  255. var s Scratch
  256. buf0, err := test.fn()
  257. if err != nil {
  258. t.Fatal(err)
  259. }
  260. if len(buf0) > BlockSizeMax {
  261. buf0 = buf0[:BlockSizeMax]
  262. }
  263. b, re, err := Compress4X(buf0, &s)
  264. if err != test.err4X {
  265. t.Errorf("want error %v (%T), got %v (%T)", test.err1X, test.err4X, err, err)
  266. }
  267. if err != nil {
  268. t.Log(test.name, err.Error())
  269. return
  270. }
  271. if b == nil {
  272. t.Error("got no output")
  273. return
  274. }
  275. if len(s.OutTable) == 0 {
  276. t.Error("got no table definition")
  277. }
  278. if re {
  279. t.Error("claimed to have re-used.")
  280. }
  281. if len(s.OutData) == 0 {
  282. t.Error("got no data output")
  283. }
  284. t.Logf("%s: %d -> %d bytes (%.2f:1) %t (table: %d bytes)", test.name, len(buf0), len(b), float64(len(buf0))/float64(len(b)), re, len(s.OutTable))
  285. })
  286. }
  287. }
  288. func TestCompress4XReuse(t *testing.T) {
  289. rng := rand.NewSource(0x1337)
  290. var s Scratch
  291. s.Reuse = ReusePolicyAllow
  292. for i := 0; i < 255; i++ {
  293. if testing.Short() && i > 10 {
  294. break
  295. }
  296. t.Run(fmt.Sprint("test-", i), func(t *testing.T) {
  297. buf0 := make([]byte, BlockSizeMax)
  298. for j := range buf0 {
  299. buf0[j] = byte(int64(i) + (rng.Int63() & 3))
  300. }
  301. b, re, err := Compress4X(buf0, &s)
  302. if err != nil {
  303. t.Fatal(err)
  304. }
  305. if b == nil {
  306. t.Error("got no output")
  307. return
  308. }
  309. if len(s.OutData) == 0 {
  310. t.Error("got no data output")
  311. }
  312. if re {
  313. t.Error("claimed to have re-used. Unlikely.")
  314. }
  315. t.Logf("%s: %d -> %d bytes (%.2f:1) %t (table: %d bytes)", t.Name(), len(buf0), len(b), float64(len(buf0))/float64(len(b)), re, len(s.OutTable))
  316. })
  317. }
  318. }
  319. func TestCompress4XReuseActually(t *testing.T) {
  320. rng := rand.NewSource(0x1337)
  321. var s Scratch
  322. s.Reuse = ReusePolicyAllow
  323. for i := 0; i < 255; i++ {
  324. if testing.Short() && i > 10 {
  325. break
  326. }
  327. t.Run(fmt.Sprint("test-", i), func(t *testing.T) {
  328. buf0 := make([]byte, BlockSizeMax)
  329. for j := range buf0 {
  330. buf0[j] = byte(rng.Int63() & 7)
  331. }
  332. b, re, err := Compress4X(buf0, &s)
  333. if err != nil {
  334. t.Fatal(err)
  335. }
  336. if b == nil {
  337. t.Error("got no output")
  338. return
  339. }
  340. if len(s.OutData) == 0 {
  341. t.Error("got no data output")
  342. }
  343. if re && i == 0 {
  344. t.Error("Claimed to have re-used on first loop.")
  345. }
  346. if !re && i > 0 {
  347. t.Error("Expected table to be reused")
  348. }
  349. t.Logf("%s: %d -> %d bytes (%.2f:1) %t (table: %d bytes)", t.Name(), len(buf0), len(b), float64(len(buf0))/float64(len(b)), re, len(s.OutTable))
  350. })
  351. }
  352. }
  353. func TestCompress1XReuse(t *testing.T) {
  354. for _, test := range testfiles {
  355. t.Run(test.name, func(t *testing.T) {
  356. var s Scratch
  357. buf0, err := test.fn()
  358. if err != nil {
  359. t.Fatal(err)
  360. }
  361. if len(buf0) > BlockSizeMax {
  362. buf0 = buf0[:BlockSizeMax]
  363. }
  364. b, re, err := Compress1X(buf0, &s)
  365. if err != test.err1X {
  366. t.Errorf("want error %v (%T), got %v (%T)", test.err1X, test.err1X, err, err)
  367. }
  368. if err != nil {
  369. t.Log(test.name, err.Error())
  370. return
  371. }
  372. if b == nil {
  373. t.Error("got no output")
  374. return
  375. }
  376. firstData := len(s.OutData)
  377. s.Reuse = ReusePolicyAllow
  378. b, re, err = Compress1X(buf0, &s)
  379. if err != nil {
  380. t.Errorf("got secondary error %v (%T)", err, err)
  381. return
  382. }
  383. if !re {
  384. t.Error("Didn't re-use even if data was the same")
  385. }
  386. if len(s.OutTable) != 0 {
  387. t.Error("got table definition, don't want any")
  388. }
  389. if len(s.OutData) == 0 {
  390. t.Error("got no data output")
  391. }
  392. if len(b) != firstData {
  393. t.Errorf("data length did not match first: %d, second:%d", firstData, len(b))
  394. }
  395. t.Logf("%s: %d -> %d bytes (%.2f:1) %t", test.name, len(buf0), len(b), float64(len(buf0))/float64(len(b)), re)
  396. })
  397. }
  398. }
  399. func BenchmarkDeflate(b *testing.B) {
  400. for _, tt := range testfiles {
  401. test := tt
  402. if test.err1X != nil {
  403. continue
  404. }
  405. b.Run(test.name, func(b *testing.B) {
  406. dec, err := flate.NewWriter(ioutil.Discard, flate.HuffmanOnly)
  407. if err != nil {
  408. b.Fatal(err)
  409. }
  410. if test.err1X != nil {
  411. b.Skip("skipping")
  412. }
  413. buf0, err := test.fn()
  414. if err != nil {
  415. b.Fatal(err)
  416. }
  417. if len(buf0) > BlockSizeMax {
  418. buf0 = buf0[:BlockSizeMax]
  419. }
  420. b.ResetTimer()
  421. b.ReportAllocs()
  422. b.SetBytes(int64(len(buf0)))
  423. for i := 0; i < b.N; i++ {
  424. dec.Reset(ioutil.Discard)
  425. n, err := dec.Write(buf0)
  426. if err != nil {
  427. b.Fatal(err)
  428. }
  429. if n != len(buf0) {
  430. b.Fatal("mismatch", n, len(buf0))
  431. }
  432. dec.Close()
  433. }
  434. })
  435. }
  436. }
  437. func BenchmarkCompress1XReuseNone(b *testing.B) {
  438. for _, tt := range testfiles {
  439. test := tt
  440. if test.err1X != nil {
  441. continue
  442. }
  443. b.Run(test.name, func(b *testing.B) {
  444. var s Scratch
  445. s.Reuse = ReusePolicyNone
  446. buf0, err := test.fn()
  447. if err != nil {
  448. b.Fatal(err)
  449. }
  450. if len(buf0) > BlockSizeMax {
  451. buf0 = buf0[:BlockSizeMax]
  452. }
  453. _, re, err := Compress1X(buf0, &s)
  454. if err != test.err1X {
  455. b.Fatal("unexpected error:", err)
  456. }
  457. b.ResetTimer()
  458. b.ReportAllocs()
  459. b.SetBytes(int64(len(buf0)))
  460. for i := 0; i < b.N; i++ {
  461. _, re, _ = Compress1X(buf0, &s)
  462. if re {
  463. b.Fatal("reused")
  464. }
  465. }
  466. })
  467. }
  468. }
  469. func BenchmarkCompress1XReuseAllow(b *testing.B) {
  470. for _, tt := range testfiles {
  471. test := tt
  472. if test.err1X != nil {
  473. continue
  474. }
  475. b.Run(test.name, func(b *testing.B) {
  476. var s Scratch
  477. s.Reuse = ReusePolicyAllow
  478. buf0, err := test.fn()
  479. if err != nil {
  480. b.Fatal(err)
  481. }
  482. if len(buf0) > BlockSizeMax {
  483. buf0 = buf0[:BlockSizeMax]
  484. }
  485. _, re, err := Compress1X(buf0, &s)
  486. if err != test.err1X {
  487. b.Fatal("unexpected error:", err)
  488. }
  489. b.ResetTimer()
  490. b.ReportAllocs()
  491. b.SetBytes(int64(len(buf0)))
  492. for i := 0; i < b.N; i++ {
  493. _, re, _ = Compress1X(buf0, &s)
  494. if !re {
  495. b.Fatal("not reused")
  496. }
  497. }
  498. })
  499. }
  500. }
  501. func BenchmarkCompress1XReusePrefer(b *testing.B) {
  502. for _, tt := range testfiles {
  503. test := tt
  504. if test.err1X != nil {
  505. continue
  506. }
  507. b.Run(test.name, func(b *testing.B) {
  508. var s Scratch
  509. s.Reuse = ReusePolicyPrefer
  510. buf0, err := test.fn()
  511. if err != nil {
  512. b.Fatal(err)
  513. }
  514. if len(buf0) > BlockSizeMax {
  515. buf0 = buf0[:BlockSizeMax]
  516. }
  517. _, re, err := Compress1X(buf0, &s)
  518. if err != test.err1X {
  519. b.Fatal("unexpected error:", err)
  520. }
  521. b.ResetTimer()
  522. b.ReportAllocs()
  523. b.SetBytes(int64(len(buf0)))
  524. for i := 0; i < b.N; i++ {
  525. _, re, _ = Compress1X(buf0, &s)
  526. if !re {
  527. b.Fatal("not reused")
  528. }
  529. }
  530. })
  531. }
  532. }
  533. func BenchmarkCompress4XReuseNone(b *testing.B) {
  534. for _, tt := range testfiles {
  535. test := tt
  536. if test.err4X != nil {
  537. continue
  538. }
  539. b.Run(test.name, func(b *testing.B) {
  540. var s Scratch
  541. s.Reuse = ReusePolicyNone
  542. buf0, err := test.fn()
  543. if err != nil {
  544. b.Fatal(err)
  545. }
  546. if len(buf0) > BlockSizeMax {
  547. buf0 = buf0[:BlockSizeMax]
  548. }
  549. _, re, err := Compress4X(buf0, &s)
  550. if err != test.err1X {
  551. b.Fatal("unexpected error:", err)
  552. }
  553. b.ResetTimer()
  554. b.ReportAllocs()
  555. b.SetBytes(int64(len(buf0)))
  556. for i := 0; i < b.N; i++ {
  557. _, re, _ = Compress4X(buf0, &s)
  558. if re {
  559. b.Fatal("reused")
  560. }
  561. }
  562. })
  563. }
  564. }
  565. func BenchmarkCompress4XReuseAllow(b *testing.B) {
  566. for _, tt := range testfiles {
  567. test := tt
  568. if test.err4X != nil {
  569. continue
  570. }
  571. b.Run(test.name, func(b *testing.B) {
  572. var s Scratch
  573. s.Reuse = ReusePolicyAllow
  574. buf0, err := test.fn()
  575. if err != nil {
  576. b.Fatal(err)
  577. }
  578. if len(buf0) > BlockSizeMax {
  579. buf0 = buf0[:BlockSizeMax]
  580. }
  581. _, re, err := Compress4X(buf0, &s)
  582. if err != test.err1X {
  583. b.Fatal("unexpected error:", err)
  584. }
  585. b.ResetTimer()
  586. b.ReportAllocs()
  587. b.SetBytes(int64(len(buf0)))
  588. for i := 0; i < b.N; i++ {
  589. _, re, _ = Compress4X(buf0, &s)
  590. if !re {
  591. b.Fatal("not reused")
  592. }
  593. }
  594. })
  595. }
  596. }
  597. func BenchmarkCompress4XReusePrefer(b *testing.B) {
  598. for _, tt := range testfiles {
  599. test := tt
  600. if test.err4X != nil {
  601. continue
  602. }
  603. b.Run(test.name, func(b *testing.B) {
  604. var s Scratch
  605. s.Reuse = ReusePolicyPrefer
  606. buf0, err := test.fn()
  607. if err != nil {
  608. b.Fatal(err)
  609. }
  610. if len(buf0) > BlockSizeMax {
  611. buf0 = buf0[:BlockSizeMax]
  612. }
  613. _, re, err := Compress4X(buf0, &s)
  614. if err != test.err4X {
  615. b.Fatal("unexpected error:", err)
  616. }
  617. b.ResetTimer()
  618. b.ReportAllocs()
  619. b.SetBytes(int64(len(buf0)))
  620. for i := 0; i < b.N; i++ {
  621. _, re, _ = Compress4X(buf0, &s)
  622. if !re {
  623. b.Fatal("not reused")
  624. }
  625. }
  626. })
  627. }
  628. }
  629. func BenchmarkCompress1XSizes(b *testing.B) {
  630. test := testfiles[0]
  631. sizes := []int{1e2, 2e2, 5e2, 1e3, 5e3, 1e4, 5e4}
  632. for _, size := range sizes {
  633. b.Run(test.name+"-"+fmt.Sprint(size), func(b *testing.B) {
  634. var s Scratch
  635. s.Reuse = ReusePolicyNone
  636. buf0, err := test.fn()
  637. if err != nil {
  638. b.Fatal(err)
  639. }
  640. buf0 = buf0[:size]
  641. _, re, err := Compress1X(buf0, &s)
  642. if err != test.err1X {
  643. b.Fatal("unexpected error:", err)
  644. }
  645. //b.Log("Size:", len(o))
  646. b.ResetTimer()
  647. b.ReportAllocs()
  648. b.SetBytes(int64(len(buf0)))
  649. for i := 0; i < b.N; i++ {
  650. _, re, _ = Compress1X(buf0, &s)
  651. if re {
  652. b.Fatal("reused")
  653. }
  654. }
  655. })
  656. }
  657. }
  658. func BenchmarkCompress4XSizes(b *testing.B) {
  659. test := testfiles[0]
  660. sizes := []int{1e2, 2e2, 5e2, 1e3, 5e3, 1e4, 5e4}
  661. for _, size := range sizes {
  662. b.Run(test.name+"-"+fmt.Sprint(size), func(b *testing.B) {
  663. var s Scratch
  664. s.Reuse = ReusePolicyNone
  665. buf0, err := test.fn()
  666. if err != nil {
  667. b.Fatal(err)
  668. }
  669. buf0 = buf0[:size]
  670. _, re, err := Compress4X(buf0, &s)
  671. if err != test.err1X {
  672. b.Fatal("unexpected error:", err)
  673. }
  674. //b.Log("Size:", len(o))
  675. b.ResetTimer()
  676. b.ReportAllocs()
  677. b.SetBytes(int64(len(buf0)))
  678. for i := 0; i < b.N; i++ {
  679. _, re, _ = Compress4X(buf0, &s)
  680. if re {
  681. b.Fatal("reused")
  682. }
  683. }
  684. })
  685. }
  686. }