Skip to content

Commit

Permalink
优化字段大小比较
Browse files Browse the repository at this point in the history
  • Loading branch information
steden committed Nov 21, 2024
1 parent b843f86 commit a7f3f80
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 49 deletions.
9 changes: 5 additions & 4 deletions compareValue.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ package collections

import (
"fmt"
"reflect"
"time"

"github.com/farseer-go/fs/dateTime"
"github.com/farseer-go/fs/fastReflect"
"github.com/farseer-go/fs/parse"
"reflect"
"time"
)

// CompareLeftGreaterThanRight 比较两个值,左值是否大于右值
func CompareLeftGreaterThanRight(leftValue any, rightValue any) bool {
pointerMeta := fastReflect.PointerOf(leftValue)
func CompareLeftGreaterThanRight(pointerMeta fastReflect.PointerMeta, leftValue any, rightValue any) bool {
//pointerMeta := fastReflect.PointerOf(leftValue)
if pointerMeta.IsEmum {
leftValue = parse.ToInt(leftValue)
rightValue = parse.ToInt(rightValue)
Expand Down
35 changes: 22 additions & 13 deletions enumerable.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"sync"
"time"

"github.com/farseer-go/fs/fastReflect"
"github.com/farseer-go/fs/parse"
"github.com/farseer-go/fs/types"
"github.com/timandy/routine"
Expand Down Expand Up @@ -341,9 +342,10 @@ func (receiver Enumerable[T]) Min(fn func(item T) any) any {
return fn(t) // 不能直接返回0
}
minValue := fn(lst[0])
pointerMeta := fastReflect.PointerOf(minValue)
for index := 1; index < len(lst); index++ {
value := fn(lst[index])
if CompareLeftGreaterThanRight(minValue, value) {
if CompareLeftGreaterThanRight(pointerMeta, minValue, value) {
minValue = value
}
}
Expand All @@ -367,9 +369,10 @@ func (receiver Enumerable[T]) MinItem() T {
return t
}
minValue := lst[0]
pointerMeta := fastReflect.PointerOf(minValue)
for index := 1; index < len(lst); index++ {
value := lst[index]
if CompareLeftGreaterThanRight(minValue, value) {
if CompareLeftGreaterThanRight(pointerMeta, minValue, value) {
minValue = value
}
}
Expand All @@ -394,9 +397,10 @@ func (receiver Enumerable[T]) Max(fn func(item T) any) any {
}

maxValue := fn(lst[0])
pointerMeta := fastReflect.PointerOf(maxValue)
for index := 1; index < len(lst); index++ {
value := fn(lst[index])
if CompareLeftGreaterThanRight(value, maxValue) {
if CompareLeftGreaterThanRight(pointerMeta, value, maxValue) {
maxValue = value
}
}
Expand All @@ -420,9 +424,10 @@ func (receiver Enumerable[T]) MaxItem() T {
return t
}
maxValue := lst[0]
pointerMeta := fastReflect.PointerOf(maxValue)
for index := 1; index < len(lst); index++ {
value := lst[index]
if CompareLeftGreaterThanRight(value, maxValue) {
if CompareLeftGreaterThanRight(pointerMeta, value, maxValue) {
maxValue = value
}
}
Expand Down Expand Up @@ -493,7 +498,7 @@ func (receiver Enumerable[T]) GroupBy(mapSlice any, getMapKeyFunc func(item T) a

// OrderBy 正序排序,fn 返回的是要排序的字段的值
func (receiver Enumerable[T]) OrderBy(fn func(item T) any) Enumerable[T] {
if receiver.lock == nil {
if receiver.lock == nil || len(*receiver.source) == 0 {
return receiver
}

Expand All @@ -502,18 +507,19 @@ func (receiver Enumerable[T]) OrderBy(fn func(item T) any) Enumerable[T] {

var lst []T
lst = append(lst, *receiver.source...)
pointerMeta := fastReflect.PointerOf(fn(lst[0]))

sort.SliceStable(lst, func(i, j int) bool {
leftValue := fn(lst[i])
rightValue := fn(lst[j])
return !CompareLeftGreaterThanRight(leftValue, rightValue)
return !CompareLeftGreaterThanRight(pointerMeta, leftValue, rightValue)
})
return Enumerable[T]{source: &lst, lock: &sync.RWMutex{}}
}

// OrderByThen 自定义多条件,返回true时,排在前面
func (receiver Enumerable[T]) OrderByThen(fn func(leftItem, rightItem T) bool) Enumerable[T] {
if receiver.lock == nil {
if receiver.lock == nil || len(*receiver.source) == 0 {
return receiver
}

Expand All @@ -531,7 +537,7 @@ func (receiver Enumerable[T]) OrderByThen(fn func(leftItem, rightItem T) bool) E

// OrderByItem 正序排序,fn 返回的是要排序的字段的值
func (receiver Enumerable[T]) OrderByItem() Enumerable[T] {
if receiver.lock == nil {
if receiver.lock == nil || len(*receiver.source) == 0 {
return receiver
}

Expand All @@ -540,18 +546,19 @@ func (receiver Enumerable[T]) OrderByItem() Enumerable[T] {

var lst []T
lst = append(lst, *receiver.source...)
pointerMeta := fastReflect.PointerOf(lst[0])

sort.SliceStable(lst, func(i, j int) bool {
leftValue := lst[i]
rightValue := lst[j]
return !CompareLeftGreaterThanRight(leftValue, rightValue)
return !CompareLeftGreaterThanRight(pointerMeta, leftValue, rightValue)
})
return Enumerable[T]{source: &lst, lock: &sync.RWMutex{}}
}

// OrderByDescending 倒序排序,fn 返回的是要排序的字段的值
func (receiver Enumerable[T]) OrderByDescending(fn func(item T) any) Enumerable[T] {
if receiver.lock == nil {
if receiver.lock == nil || len(*receiver.source) == 0 {
return receiver
}

Expand All @@ -560,18 +567,19 @@ func (receiver Enumerable[T]) OrderByDescending(fn func(item T) any) Enumerable[

var lst []T
lst = append(lst, *receiver.source...)
pointerMeta := fastReflect.PointerOf(fn(lst[0]))

sort.SliceStable(lst, func(i, j int) bool {
leftValue := fn(lst[i])
rightValue := fn(lst[j])
return CompareLeftGreaterThanRight(leftValue, rightValue)
return CompareLeftGreaterThanRight(pointerMeta, leftValue, rightValue)
})
return Enumerable[T]{source: &lst, lock: &sync.RWMutex{}}
}

// OrderByDescendingItem 倒序排序,fn 返回的是要排序的字段的值
func (receiver Enumerable[T]) OrderByDescendingItem() Enumerable[T] {
if receiver.lock == nil {
if receiver.lock == nil || len(*receiver.source) == 0 {
return receiver
}

Expand All @@ -580,11 +588,12 @@ func (receiver Enumerable[T]) OrderByDescendingItem() Enumerable[T] {

var lst []T
lst = append(lst, *receiver.source...)
pointerMeta := fastReflect.PointerOf(lst[0])

sort.SliceStable(lst, func(i, j int) bool {
leftValue := lst[i]
rightValue := lst[j]
return CompareLeftGreaterThanRight(leftValue, rightValue)
return CompareLeftGreaterThanRight(pointerMeta, leftValue, rightValue)
})
return Enumerable[T]{source: &lst, lock: &sync.RWMutex{}}
}
Expand Down
78 changes: 47 additions & 31 deletions test/compareValue_test.go
Original file line number Diff line number Diff line change
@@ -1,55 +1,71 @@
package test

import (
"testing"

"github.com/farseer-go/collections"
"github.com/farseer-go/fs/fastReflect"
"github.com/stretchr/testify/assert"
"testing"
)

func TestCompareLeftGreaterThanRight(t *testing.T) {
assert.False(t, collections.CompareLeftGreaterThanRight(int(1), int(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(int(5), int(1)))
pointerMeta := fastReflect.PointerOf(int(1))
assert.False(t, collections.CompareLeftGreaterThanRight(pointerMeta, int(1), int(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(pointerMeta, int(5), int(1)))

assert.False(t, collections.CompareLeftGreaterThanRight(int8(1), int8(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(int8(5), int8(1)))
pointerMeta = fastReflect.PointerOf(int8(1))
assert.False(t, collections.CompareLeftGreaterThanRight(pointerMeta, int8(1), int8(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(pointerMeta, int8(5), int8(1)))

assert.False(t, collections.CompareLeftGreaterThanRight(int16(1), int16(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(int16(5), int16(1)))
pointerMeta = fastReflect.PointerOf(int16(1))
assert.False(t, collections.CompareLeftGreaterThanRight(pointerMeta, int16(1), int16(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(pointerMeta, int16(5), int16(1)))

assert.False(t, collections.CompareLeftGreaterThanRight(int32(1), int32(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(int32(5), int32(1)))
pointerMeta = fastReflect.PointerOf(int32(1))
assert.False(t, collections.CompareLeftGreaterThanRight(pointerMeta, int32(1), int32(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(pointerMeta, int32(5), int32(1)))

assert.False(t, collections.CompareLeftGreaterThanRight(int64(1), int64(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(int64(5), int64(1)))
pointerMeta = fastReflect.PointerOf(int64(1))
assert.False(t, collections.CompareLeftGreaterThanRight(pointerMeta, int64(1), int64(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(pointerMeta, int64(5), int64(1)))

assert.False(t, collections.CompareLeftGreaterThanRight(uint(1), uint(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(uint(5), uint(1)))
pointerMeta = fastReflect.PointerOf(uint(1))
assert.False(t, collections.CompareLeftGreaterThanRight(pointerMeta, uint(1), uint(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(pointerMeta, uint(5), uint(1)))

assert.False(t, collections.CompareLeftGreaterThanRight(uint8(1), uint8(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(uint8(5), uint8(1)))
pointerMeta = fastReflect.PointerOf(uint8(1))
assert.False(t, collections.CompareLeftGreaterThanRight(pointerMeta, uint8(1), uint8(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(pointerMeta, uint8(5), uint8(1)))

assert.False(t, collections.CompareLeftGreaterThanRight(uint16(1), uint16(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(uint16(5), uint16(1)))
pointerMeta = fastReflect.PointerOf(uint16(1))
assert.False(t, collections.CompareLeftGreaterThanRight(pointerMeta, uint16(1), uint16(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(pointerMeta, uint16(5), uint16(1)))

assert.False(t, collections.CompareLeftGreaterThanRight(uint32(1), uint32(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(uint32(5), uint32(1)))
pointerMeta = fastReflect.PointerOf(uint32(1))
assert.False(t, collections.CompareLeftGreaterThanRight(pointerMeta, uint32(1), uint32(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(pointerMeta, uint32(5), uint32(1)))

assert.False(t, collections.CompareLeftGreaterThanRight(uint64(1), uint64(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(uint64(5), uint64(1)))
pointerMeta = fastReflect.PointerOf(uint64(1))
assert.False(t, collections.CompareLeftGreaterThanRight(pointerMeta, uint64(1), uint64(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(pointerMeta, uint64(5), uint64(1)))

assert.False(t, collections.CompareLeftGreaterThanRight(float32(1), float32(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(float32(5), float32(1)))
pointerMeta = fastReflect.PointerOf(float32(1))
assert.False(t, collections.CompareLeftGreaterThanRight(pointerMeta, float32(1), float32(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(pointerMeta, float32(5), float32(1)))

assert.False(t, collections.CompareLeftGreaterThanRight(float64(1), float64(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(float64(5), float64(1)))
pointerMeta = fastReflect.PointerOf(float64(1))
assert.False(t, collections.CompareLeftGreaterThanRight(pointerMeta, float64(1), float64(5)))
assert.True(t, collections.CompareLeftGreaterThanRight(pointerMeta, float64(5), float64(1)))

assert.False(t, collections.CompareLeftGreaterThanRight("a", "b"))
assert.False(t, collections.CompareLeftGreaterThanRight("aa", "ab"))
assert.True(t, collections.CompareLeftGreaterThanRight("", "ab"))
assert.True(t, collections.CompareLeftGreaterThanRight("aba", "ab"))
assert.False(t, collections.CompareLeftGreaterThanRight("aa", "aaa"))
pointerMeta = fastReflect.PointerOf("")
assert.False(t, collections.CompareLeftGreaterThanRight(pointerMeta, "a", "b"))
assert.False(t, collections.CompareLeftGreaterThanRight(pointerMeta, "aa", "ab"))
assert.True(t, collections.CompareLeftGreaterThanRight(pointerMeta, "", "ab"))
assert.True(t, collections.CompareLeftGreaterThanRight(pointerMeta, "aba", "ab"))
assert.False(t, collections.CompareLeftGreaterThanRight(pointerMeta, "aa", "aaa"))

assert.Panics(t, func() {
collections.CompareLeftGreaterThanRight([]int{}, []int{})
pointerMeta = fastReflect.PointerOf([]int{})
collections.CompareLeftGreaterThanRight(pointerMeta, []int{}, []int{})
})
}
2 changes: 1 addition & 1 deletion test/sort_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ type family struct {
}

// BenchmarkOrderBy-10 2 659323792 ns/op 245808 B/op 3 allocs/op
// BenchmarkOrderBy-10 248 4913683 ns/op 245947 B/op 6 allocs/op
// BenchmarkOrderBy-10 334 3615433 ns/op 245905 B/op 6 allocs/op
func BenchmarkOrderBy(b *testing.B) {
lst := collections.NewList[family]()
for i := 0; i < 10000; i++ {
Expand Down

0 comments on commit a7f3f80

Please sign in to comment.