From 05b85a21314bce661f14636f4ba5125b717ead37 Mon Sep 17 00:00:00 2001 From: Yurun Date: Wed, 27 Nov 2024 14:58:02 +0800 Subject: [PATCH] Pre-allocate memory to reduce the number of allocations (#272) --- convertor/convertor.go | 2 +- datastructure/link/doublylink.go | 2 +- datastructure/link/singlylink.go | 2 +- datastructure/queue/arrayqueue.go | 2 +- datastructure/queue/linkedqueue.go | 2 +- datastructure/stack/linkedstack.go | 2 +- datastructure/tree/tree_internal.go | 2 +- fileutil/file.go | 6 ++++-- netutil/http.go | 2 +- stream/stream.go | 1 + structs/struct.go | 2 +- xerror/xerror.go | 2 +- 12 files changed, 15 insertions(+), 12 deletions(-) diff --git a/convertor/convertor.go b/convertor/convertor.go index 423df3bc..acf620c2 100644 --- a/convertor/convertor.go +++ b/convertor/convertor.go @@ -74,7 +74,7 @@ func ToBytes(value any) ([]byte, error) { // ToChar convert string to char slice. // Play: https://go.dev/play/p/JJ1SvbFkVdM func ToChar(s string) []string { - c := make([]string, 0) + c := make([]string, 0, len(s)) if len(s) == 0 { c = append(c, "") } diff --git a/datastructure/link/doublylink.go b/datastructure/link/doublylink.go index 4e56643d..a413deb7 100644 --- a/datastructure/link/doublylink.go +++ b/datastructure/link/doublylink.go @@ -209,7 +209,7 @@ func (dl *DoublyLink[T]) Size() int { // Values return slice of all doubly linklist node value func (dl *DoublyLink[T]) Values() []T { - result := []T{} + result := make([]T, 0, dl.length) current := dl.Head for current != nil { result = append(result, current.Value) diff --git a/datastructure/link/singlylink.go b/datastructure/link/singlylink.go index 401325a9..790cdd9e 100644 --- a/datastructure/link/singlylink.go +++ b/datastructure/link/singlylink.go @@ -212,7 +212,7 @@ func (sl *SinglyLink[T]) Size() int { // Values return slice of all singly linklist node value func (sl *SinglyLink[T]) Values() []T { - result := []T{} + result := make([]T, 0, sl.length) current := sl.Head for current != nil { result = append(result, current.Value) diff --git a/datastructure/queue/arrayqueue.go b/datastructure/queue/arrayqueue.go index 76f0c1b0..d50b93bb 100644 --- a/datastructure/queue/arrayqueue.go +++ b/datastructure/queue/arrayqueue.go @@ -31,7 +31,7 @@ func NewArrayQueue[T any](capacity int) *ArrayQueue[T] { // Data return slice of queue data func (q *ArrayQueue[T]) Data() []T { - items := []T{} + items := make([]T, 0, q.tail-q.head) for i := q.head; i < q.tail; i++ { items = append(items, q.data[i]) } diff --git a/datastructure/queue/linkedqueue.go b/datastructure/queue/linkedqueue.go index d44cfd7a..789ca02c 100644 --- a/datastructure/queue/linkedqueue.go +++ b/datastructure/queue/linkedqueue.go @@ -27,7 +27,7 @@ func NewLinkedQueue[T any]() *LinkedQueue[T] { // Data return slice of queue data func (q *LinkedQueue[T]) Data() []T { - res := []T{} + res := make([]T, 0, q.length) current := q.head for current != nil { diff --git a/datastructure/stack/linkedstack.go b/datastructure/stack/linkedstack.go index af17846f..02d9a921 100644 --- a/datastructure/stack/linkedstack.go +++ b/datastructure/stack/linkedstack.go @@ -24,7 +24,7 @@ func NewLinkedStack[T any]() *LinkedStack[T] { // Data return stack data func (s *LinkedStack[T]) Data() []T { - res := []T{} + res := make([]T, 0, s.length) current := s.top for current != nil { diff --git a/datastructure/tree/tree_internal.go b/datastructure/tree/tree_internal.go index 5151a0df..424d34db 100644 --- a/datastructure/tree/tree_internal.go +++ b/datastructure/tree/tree_internal.go @@ -147,7 +147,7 @@ func printTreeNodes[T any](nodes []*datastructure.TreeNode[T], level, maxLevel i printSpaces(firstSpaces) - newNodes := []*datastructure.TreeNode[T]{} + newNodes := make([]*datastructure.TreeNode[T], 0, len(nodes)*2) for _, node := range nodes { if node != nil { fmt.Printf("%v", node.Value) diff --git a/fileutil/file.go b/fileutil/file.go index cb72c191..b131ee72 100644 --- a/fileutil/file.go +++ b/fileutil/file.go @@ -14,7 +14,6 @@ import ( "encoding/csv" "errors" "fmt" - "github.com/duke-git/lancet/v2/validator" "io" "io/fs" "net/http" @@ -24,6 +23,8 @@ import ( "sort" "strings" "sync" + + "github.com/duke-git/lancet/v2/validator" ) // FileReader is a reader supporting offset seeking and reading one @@ -819,6 +820,7 @@ func WriteMapsToCsv(filepath string, records []map[string]any, appendToExistingF if len(headers) > 0 { columnHeaders = headers[0] } else { + columnHeaders = make([]string, 0, len(records[0])) for key := range records[0] { columnHeaders = append(columnHeaders, key) } @@ -832,7 +834,7 @@ func WriteMapsToCsv(filepath string, records []map[string]any, appendToExistingF } for _, record := range records { - var row []string + row := make([]string, 0, len(columnHeaders)) for _, h := range columnHeaders { row = append(row, fmt.Sprintf("%v", record[h])) } diff --git a/netutil/http.go b/netutil/http.go index aaa3bf25..5fa0d194 100644 --- a/netutil/http.go +++ b/netutil/http.go @@ -71,7 +71,7 @@ func ConvertMapToQueryString(param map[string]any) string { if param == nil { return "" } - var keys []string + keys := make([]string, 0, len(param)) for key := range param { keys = append(keys, key) } diff --git a/stream/stream.go b/stream/stream.go index 337587fc..f49792ad 100644 --- a/stream/stream.go +++ b/stream/stream.go @@ -202,6 +202,7 @@ func (s Stream[T]) Skip(n int) Stream[T] { return FromSlice(source) } + source = make([]T, 0, l-n) for i := n; i < l; i++ { source = append(source, s.source[i]) } diff --git a/structs/struct.go b/structs/struct.go index ed732024..54819187 100644 --- a/structs/struct.go +++ b/structs/struct.go @@ -88,8 +88,8 @@ func (s *Struct) ToMap() (map[string]any, error) { // Fields returns all the struct fields within a slice func (s *Struct) Fields() []*Field { - var fields []*Field fieldNum := s.rvalue.NumField() + fields := make([]*Field, 0, fieldNum) for i := 0; i < fieldNum; i++ { v := s.rvalue.Field(i) sf := s.rtype.Field(i) diff --git a/xerror/xerror.go b/xerror/xerror.go index 24320043..856dc13b 100644 --- a/xerror/xerror.go +++ b/xerror/xerror.go @@ -34,7 +34,7 @@ func Wrap(cause error, message ...any) *XError { err := newXError() if len(message) > 0 { - var newMsgs []string + newMsgs := make([]string, 0, len(message)) for _, m := range message { newMsgs = append(newMsgs, fmt.Sprintf("%v", m)) }