Optimization for vector

This commit is contained in:
emilis 2022-08-02 15:49:10 +01:00
parent 97014203e4
commit 0d2936b91b
3 changed files with 60 additions and 97 deletions

View File

@ -1,19 +0,0 @@
package coll
type Iterator[T any] Vector[T]
func (i Iterator[T]) ForEach(f func(int, T)) {
for index := 0; index < i.length; index++ {
f(index, i.array[index])
}
}
func (i Iterator[T]) ForBreak(f func(index int, t T, breaker func())) {
var broke bool
brk := func() {
broke = true
}
for index := 0; index < i.length || !broke; index++ {
f(index, i.array[index], brk)
}
}

View File

@ -2,43 +2,41 @@
package coll
func Map[T, V any](c Vector[T], f func(T) V) Vector[V] {
out := make([]V, c.length)
for index := 0; index < c.length; index++ {
out[index] = f(c.array[index])
out := make([]V, len(c))
for index := 0; index < len(c); index++ {
out[index] = f(c[index])
}
return From(out)
}
func Filter[T any](v Vector[T], f func(T) bool) Vector[T] {
out := WithCap[T](v.length)
v.Iterate().ForEach(func(_ int, t T) {
out := WithCap[T](len(v))
for _, t := range v {
if f(t) {
out.Push(t)
}
})
}
return out
}
func Take[T any](v Vector[T], howMany int) Vector[T] {
if v.length == 0 {
if len(v) == 0 {
return New[T]()
}
if v.length < howMany {
howMany = v.length
if len(v) < howMany {
howMany = len(v)
}
return From(v.array[:howMany-1])
return From(v[:howMany-1])
}
func Any[T any](v Vector[T], f func(T) bool) bool {
var found bool
v.Iterate().ForBreak(func(_ int, t T, breaker func()) {
for _, t := range v {
if f(t) {
found = true
breaker()
return true
}
})
return found
}
return false
}
type numeric interface {
@ -47,26 +45,25 @@ type numeric interface {
func Min[T numeric](v Vector[T]) T {
var min T
if v.length == 0 {
if len(v) == 0 {
return min
}
min = v.array[0]
v.Iterate().ForEach(func(_ int, t T) {
min = v[0]
for _, t := range v {
if min > t {
min = t
}
})
}
return min
}
func Max[T numeric](v Vector[T]) T {
var max T
v.Iterate().ForEach(func(_ int, t T) {
for _, t := range v {
if max < t {
max = t
}
})
}
return max
}

View File

@ -6,143 +6,128 @@ const (
DefaultSize = 4
)
type Vector[T any] struct {
array []T
length int
capacity int
}
type Vector[T any] []T
func New[T any]() Vector[T] {
return WithCap[T](DefaultSize)
}
func WithCap[T any](capacity int) Vector[T] {
return Vector[T]{
array: make([]T, capacity),
length: 0,
capacity: capacity,
}
return make(Vector[T], 0, capacity)
}
func From[T any](v []T) Vector[T] {
return Vector[T]{
array: v,
length: len(v),
capacity: len(v),
}
return Vector[T](v)
}
func (v Vector[T]) Push(t T) Vector[T] {
if v.length == v.capacity {
if len(v) == cap(v) {
v = v.upsize()
}
v.array[v.length] = t
v.length++
v = v[:len(v)+1]
v[len(v)-1] = t
return v
}
func (v Vector[T]) Append(t ...T) Vector[T] {
if v.capacity-v.length < len(t) {
if cap(v)-len(v) < len(t) {
v = v.upsizeSpecific(len(t))
}
startLen := len(v)
v = v[:len(v)+len(t)]
var tIndex int
for ; v.length < v.capacity; v.length++ {
v.array[v.length] = t[tIndex]
for index := startLen; index < cap(v); index++ {
v[index] = t[tIndex]
tIndex++
}
return v
}
func (v Vector[T]) Remove(index int) Vector[T] {
return From(append(v.array[:index], v.array[index+1:v.length]...))
return From(append(v[:index], v[index+1:]...))
}
// Faster remove function that can be used on vectors where ordering doesn't matter
func (v Vector[T]) RemoveUnordered(index int) Vector[T] {
v.length--
v.array[index] = v.array[v.length]
return v
v[index] = v[len(v)-1]
return v[:len(v)-1]
}
func (v Vector[T]) upsize() Vector[T] {
return v.upsizeSpecific(v.capacity)
return v.upsizeSpecific(cap(v))
}
func (v Vector[T]) upsizeSpecific(extraSize int) Vector[T] {
v.array = append(v.array, make([]T, extraSize)...)
v.capacity = len(v.array)
return v
fmt.Println(cap(v), extraSize)
resized := make([]T, len(v), cap(v)+extraSize)
copy(resized, v)
return resized
}
func (v Vector[T]) Slice() []T {
if v.length == 0 {
if len(v) == 0 {
return []T{}
}
return v.array[:v.length]
return v[:len(v)]
}
func (v Vector[T]) panicIndex(index int) {
min := -1
if v.length != 0 {
if len(v) != 0 {
min = 0
}
panic(fmt.Sprintf("index %d out of range [%d;%d)", index, min, v.length))
panic(fmt.Sprintf("index %d out of range [%d;%d)", index, min, len(v)))
}
// GetSoft tries to get the requested index, or returns a default value if
// it's out of range
func (v Vector[T]) GetSoft(index int) T {
var result T
if index < 0 || index >= v.length {
if index < 0 || index >= len(v) {
return result
}
return v.array[index]
return v[index]
}
func (v Vector[T]) Get(index int) T {
if index < 0 || index >= v.length {
if index < 0 || index >= len(v) {
v.panicIndex(index)
}
return v.array[index]
return v[index]
}
func (v Vector[T]) Set(index int, value T) Vector[T] {
if index < 0 || index >= v.length {
if index < 0 || index >= len(v) {
v.panicIndex(index)
}
v.array[index] = value
v[index] = value
return v
}
func (v Vector[T]) Len() int {
return v.length
}
func (v Vector[T]) Iterate() Iterator[T] {
return Iterator[T](v)
return len(v)
}
func (v Vector[T]) Pop() (T, Vector[T]) {
v.length--
t := v.array[v.length]
return t, v
t := v[len(v)-1]
return t, v[:len(v)-1]
}
func (v Vector[T]) Sub(start, end int) Vector[T] {
if start >= v.length {
if start >= len(v) {
v.panicIndex(start)
}
if end >= v.length {
if end >= len(v) {
v.panicIndex(end)
}
if start < 0 {
return From(v.array[:end])
return From(v[:end])
}
if end < 0 {
return From(v.array[start:])
return From(v[start:])
}
return From(v.array[start:end])
return From(v[start:end])
}
func (v Vector[T]) Filter(f func(T) bool) Vector[T] {
@ -158,8 +143,8 @@ func (v Vector[T]) Take(howMany int) Vector[T] {
}
func (v Vector[T]) Clone() Vector[T] {
clone := make([]T, len(v.array))
copy(clone, v.array)
v.array = clone
clone := make([]T, len(v))
copy(clone, v)
v = clone
return v
}