{"id":17335703,"url":"https://github.com/fufuok/bytespool","last_synced_at":"2025-04-14T17:30:33.715Z","repository":{"id":112342536,"uuid":"421904371","full_name":"fufuok/bytespool","owner":"fufuok","description":"🔥 BytesPool, Reuse used byte slices to achieve zero allocation.","archived":false,"fork":false,"pushed_at":"2024-08-27T05:02:11.000Z","size":114,"stargazers_count":11,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-08-27T05:47:07.636Z","etag":null,"topics":["bytebufferpool","byteslicepool"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fufuok.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-10-27T17:03:01.000Z","updated_at":"2024-08-27T04:48:53.000Z","dependencies_parsed_at":"2024-03-26T10:51:06.140Z","dependency_job_id":"f5faf0f3-6a36-43c4-b169-557c24235f05","html_url":"https://github.com/fufuok/bytespool","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fufuok%2Fbytespool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fufuok%2Fbytespool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fufuok%2Fbytespool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fufuok%2Fbytespool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fufuok","download_url":"https://codeload.github.com/fufuok/bytespool/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219843488,"owners_count":16556504,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bytebufferpool","byteslicepool"],"created_at":"2024-10-15T15:11:54.057Z","updated_at":"2024-10-15T15:11:54.890Z","avatar_url":"https://github.com/fufuok.png","language":"Go","readme":"# 💫 BytesPool\n\nReuse used byte slices to achieve zero allocation.\n\nThe existing byte slices are stored in groups according to the capacity length range, and suitable byte slice objects are automatically allocated according to the capacity length when used.\n\n## ✨ Features\n\n- Customize the capacity range, or use the default pool.\n- Get byte slices always succeed without panic.\n- Optional length of 0 or fixed-length byte slices.\n- Automatic garbage collection of big-byte slices.\n- [BufPool](#-BufPool) implements the httputil.BufferPool interface.\n- [Buffer](#-buffer) similar to bytes.Buffer, low-level byte slice multiplexing.\n- High performance, See: [Benchmarks](#-benchmarks).\n\n## ⚙️ Installation\n\n```go\ngo get -u github.com/fufuok/bytespool\n```\n\n## 📚 Examples\n\nPlease see: [examples](examples)\n\nRelease warning: [examples/warning](examples/warning)\n\nSimple reverse proxy: [examples/reverse_proxy](examples/reverse_proxy)\n\n```go\npackage bytespool // import \"github.com/fufuok/bytespool\"\n\nvar DefaultCapacityPools = NewCapacityPools(defaultMinSize, defaultMaxSize)\nfunc Append(buf []byte, elems ...byte) []byte\nfunc AppendString(buf []byte, elems string) []byte\nfunc Clone(buf []byte) []byte\nfunc Get(size int) []byte\nfunc InitDefaultPools(minSize, maxSize int)\nfunc Make(capacity int) []byte\nfunc Make64(capacity uint64) []byte\nfunc MakeMax() []byte\nfunc MakeMin() []byte\nfunc MaxSize() int\nfunc MinSize() int\nfunc New(size int) []byte\nfunc New64(size uint64) []byte\nfunc NewBytes(bs []byte) []byte\nfunc NewMax() []byte\nfunc NewMin() []byte\nfunc NewString(s string) []byte\nfunc Put(buf []byte)\nfunc Release(buf []byte) bool\nfunc RuntimeStats(ps ...*CapacityPools) map[string]uint64\ntype BufPool struct{ ... }\n    func NewBufPool(size int) *BufPool\ntype CapacityPools struct{ ... }\n    func NewCapacityPools(minSize, maxSize int) *CapacityPools\n```\n\n### ⚡️ Quickstart\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/fufuok/bytespool\"\n)\n\nfunc main() {\n\t// Get() is the same as New()\n\tbs := bytespool.Get(1024)\n\t// len: 1024, cap: 1024\n\tfmt.Printf(\"len: %d, cap: %d\\n\", len(bs), cap(bs))\n\n\t// Put() is the same as Release(), Put it back into the pool after use\n\tbytespool.Put(bs)\n\n\t// len: 0, capacity: 8 (Specified capacity)\n\tbs = bytespool.Make(8)\n\tbs = append(bs, \"abc\"...)\n\t// len: 3, cap: 8\n\tfmt.Printf(\"len: %d, cap: %d\\n\", len(bs), cap(bs))\n\tok := bytespool.Release(bs)\n\t// true\n\tfmt.Println(ok)\n\n\t// len: 8, capacity: 8 (Fixed length)\n\tbs = bytespool.New(8)\n\tcopy(bs, \"12345678\")\n\t// len: 8, cap: 8, value: 12345678\n\tfmt.Printf(\"len: %d, cap: %d, value: %s\\n\", len(bs), cap(bs), bs)\n\tbytespool.Release(bs)\n\n\t// len: len(\"xyz\"), capacity: 4\n\tbs = bytespool.NewString(\"xyz\")\n\t// len: 3, cap: 4, value: xyz\n\tfmt.Printf(\"len: %d, cap: %d, value: %s\\n\", len(bs), cap(bs), bs)\n\tbytespool.Release(bs)\n\n\t// Output:\n\t// len: 1024, cap: 1024\n\t// len: 3, cap: 8\n\t// true\n\t// len: 8, cap: 8, value: 12345678\n\t// len: 3, cap: 4, value: xyz\n}\n```\n\n### ⏳ Automated reuse\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/fufuok/bytespool\"\n)\n\nfunc main() {\n\t// len: 0, cap: 4 (Specified capacity, automatically adapt to the capacity scale)\n\tbs3 := bytespool.Make(3)\n\n\tbs3 = append(bs3, \"123\"...)\n\tfmt.Printf(\"len: %d, cap: %d, %s\\n\", len(bs3), cap(bs3), bs3)\n\n\tbytespool.Release(bs3)\n\n\t// len: 4, cap: 4 (Fixed length)\n\tbs4 := bytespool.New(4)\n\n\t// Reuse of bs3\n\tfmt.Printf(\"same array: %v\\n\", \u0026bs3[0] == \u0026bs4[0])\n\t// Contain old data\n\tfmt.Printf(\"bs3: %s, bs4: %s\\n\", bs3, bs4[:3])\n\n\tcopy(bs4, \"xy\")\n\tfmt.Printf(\"len: %d, cap: %d, %s\\n\", len(bs4), cap(bs4), bs4[:3])\n\n\tbytespool.Release(bs4)\n\n\t// Output:\n\t// len: 3, cap: 4, 123\n\t// same array: true\n\t// bs3: 123, bs4: 123\n\t// len: 4, cap: 4, xy3\n}\n```\n\n### 🛠 Reset DefaultPools\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/fufuok/bytespool\"\n)\n\nfunc main() {\n\tbytespool.InitDefaultPools(512, 4096)\n\n\tbs := bytespool.Make(10)\n\tfmt.Printf(\"len: %d, cap: %d\\n\", len(bs), cap(bs))\n\tbytespool.Release(bs)\n\n\tbs = bytespool.MakeMax()\n\tfmt.Printf(\"len: %d, cap: %d\\n\", len(bs), cap(bs))\n\tbytespool.Release(bs)\n\n\tbs = bytespool.New(10240)\n\tfmt.Printf(\"len: %d, cap: %d\\n\", len(bs), cap(bs))\n\tok := bytespool.Release(bs)\n\tfmt.Printf(\"Discard: %v\\n\", !ok)\n\n\t// Output:\n\t// len: 0, cap: 512\n\t// len: 0, cap: 4096\n\t// len: 10240, cap: 10240\n\t// Discard: true\n}\n```\n\n### 🎨 Custom pools\n\n```go\npackage main\n\nimport (\n\t\"github.com/fufuok/bytespool\"\n)\n\nfunc main() {\n\tbspool := bytespool.NewCapacityPools(8, 1024)\n\tbs := bspool.MakeMax()\n\tbspool.Release(bs)\n\tbs = bspool.Make(64)\n\tbspool.Release(bs)\n\tbs = bspool.New(128)\n\tbspool.Release(bs)\n}\n```\n\n### ♾ BufPool\n\nUsed to get fixed-length byte slices.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/fufuok/bytespool\"\n)\n\nfunc main() {\n\tbufPool := bytespool.NewBufPool(32 * 1024)\n\tbs := bufPool.Get()\n\n\tdata := []byte(\"test\")\n\tn := copy(bs, data)\n\t// n: 4, bs: test\n\tfmt.Printf(\"n: %d, bs: %s\\n\", n, bs[:n])\n\n\tbufPool.Put(bs)\n}\n```\n\n### 🔥 Buffer\n\nSimilar to bytes.Buffer, based on bytespool.\n\n```go\npackage buffer // import \"github.com/fufuok/bytespool/buffer\"\n\nvar ErrTooLarge = errors.New(\"buffer: too large\") ...\nvar DefaultBufferSize = 64\nfunc GetReader(bs []byte) *bytes.Reader\nfunc MaxSize() int\nfunc MinSize() int\nfunc Put(bb *Buffer)\nfunc PutReader(r *bytes.Reader)\nfunc Release(bb *Buffer) (ok bool)\nfunc RuntimeStats() map[string]uint64\nfunc SetCapacity(minSize, maxSize int)\ntype Buffer struct{ ... }\n    func Clone(bb *Buffer) *Buffer\n    func Get(capacity ...int) *Buffer\n    func Make(capacity int) *Buffer\n    func Make64(capacity uint64) *Buffer\n    func MakeMax() *Buffer\n    func MakeMin() *Buffer\n    func New(size int) *Buffer\n    func NewBuffer(buf []byte) *Buffer\n    func NewBytes(bs []byte) *Buffer\n    func NewString(s string) *Buffer\n```\n\nPlease see:\n\n- [DOC](buffer)\n- [examples/buffer](examples/buffer)\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/fufuok/bytespool/buffer\"\n)\n\nfunc main() {\n\tbb := buffer.Get()\n\n\tbb.SetString(\"1\")\n\t_, _ = bb.WriteString(\"22\")\n\t_, _ = bb.Write([]byte(\"333\"))\n\t_ = bb.WriteByte('x')\n\tbb.Truncate(6)\n\n\tfmt.Println(\"bb:\", bb.String())\n\n\tbs := bb.Copy()\n\tbb.SetString(\"ff\")\n\tfmt.Println(\"bs:\", string(bs))\n\tfmt.Println(\"bb:\", bb.String())\n\n\t// After use, put Buffer back in the pool.\n\tbuffer.Put(bb)\n\t// or (safe)\n\tbb.Put()\n\t// or (safe)\n\tbb.Release()\n\n\t// Output:\n\t// bb: 122333\n\t// bs: 122333\n\t// bb: ff\n}\n```\n\n## 🤖 Benchmarks\n\n**byte slices**\n\n```go\ngo test -run=^$ -benchmem -benchtime=1s -count=2 -bench=.\ngoos: linux\ngoarch: amd64\npkg: github.com/fufuok/bytespool\ncpu: Intel(R) Xeon(R) Gold 6151 CPU @ 3.00GHz\nBenchmarkCapacityPools/New-4            56386340                21.24 ns/op            0 B/op          0 allocs/op\nBenchmarkCapacityPools/New-4            56503125                21.21 ns/op            0 B/op          0 allocs/op\nBenchmarkCapacityPools/Make-4           56200932                21.40 ns/op            0 B/op          0 allocs/op\nBenchmarkCapacityPools/Make-4           56215285                21.43 ns/op            0 B/op          0 allocs/op\nBenchmarkCapacityPools/MakeMax-4        56522522                21.15 ns/op            0 B/op          0 allocs/op\nBenchmarkCapacityPools/MakeMax-4        56000730                21.45 ns/op            0 B/op          0 allocs/op\nBenchmarkCapacityPools/New.Parallel-4           217137915                5.480 ns/op           0 B/op          0 allocs/op\nBenchmarkCapacityPools/New.Parallel-4           212783748                5.912 ns/op           0 B/op          0 allocs/op\nBenchmarkCapacityPools/Make.Parallel-4          212007224                5.541 ns/op           0 B/op          0 allocs/op\nBenchmarkCapacityPools/Make.Parallel-4          211065468                5.583 ns/op           0 B/op          0 allocs/op\nBenchmarkCapacityPools/MakeMax.Parallel-4       217466509                5.525 ns/op           0 B/op          0 allocs/op\nBenchmarkCapacityPools/MakeMax.Parallel-4       218557538                5.524 ns/op           0 B/op          0 allocs/op\n```\n\n**Buffer**\n\n```go\ngo test -bench=. -benchmem\ngoos: linux\ngoarch: amd64\npkg: github.com/fufuok/bytespool/buffer\ncpu: Intel(R) Xeon(R) Gold 6151 CPU @ 3.00GHz\nBenchmarkBuffer_Write-4         72282802                16.06 ns/op            0 B/op          0 allocs/op\nBenchmarkBuffer_Write_Std-4     65271292                18.50 ns/op            0 B/op          0 allocs/op\n```\n\n\n\n\n\n\n\n*ff*","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffufuok%2Fbytespool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffufuok%2Fbytespool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffufuok%2Fbytespool/lists"}