-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
arrays: add subtract/2 #25868
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
arrays: add subtract/2 #25868
Conversation
|
@gechandesu what if |
You're right, my english is bad... |
|
My tests show this is an equivalent function. What do you think? fn mike[T](a []T, b []T) []T {
mut result := []T{cap: a.len}
for elem in a {
if elem !in b {
result << elem
}
}
return result
} |
This is much slower on large arrays. I've tested it In the worst case ( Benchmark
import benchmark
fn mike[T](a []T, b []T) []T {
mut result := []T{cap: a.len}
for elem in a {
if elem !in b {
result << elem
}
}
return result
}
fn subtract[T](a []T, b []T) []T {
mut result := []T{cap: a.len}
mut b_set := map[T]bool{}
for elem in b {
b_set[elem] = false
}
for elem in a {
if elem !in b_set {
result << elem
}
}
return result
}
fn main() {
iters := 1
len := 100_000
a := []int{len: len, init: 1}
b := []int{len: len}
mut bench := benchmark.start()
for _ in 0 .. iters {
_ := subtract(a, b)
}
bench.measure('subtract')
for _ in 0 .. iters {
_ := mike(a, b)
}
bench.measure('mike')
}I'd like to avoid map, as it limits the input types, but the price is very low performance. Of course, I could add comptime type check and use a slower algorithm for anything that isn't supported as a |
|
For science, i would like to show where import benchmark
import rand
fn mike[T](a []T, b []T) []T {
mut result := []T{cap: a.len}
for elem in a {
if elem !in b {
result << elem
}
}
return result
}
fn subtract[T](a []T, b []T) []T {
mut result := []T{cap: a.len}
mut b_set := map[T]bool{}
for elem in b {
b_set[elem] = false
}
for elem in a {
if elem !in b_set {
result << elem
}
}
return result
}
fn main() {
iters := 1_000_000
mut bench := benchmark.start()
for _ in 0 .. iters {
a := rand.bytes(rand.u8())!
b := rand.bytes(rand.u8())!
_ := subtract(a, b)
}
bench.measure('subtract')
for _ in 0 .. iters {
a := rand.bytes(rand.u8())!
b := rand.bytes(rand.u8())!
_ := mike(a, b)
}
bench.measure('mike')
} |
|
Yes, map allocations may slow down on small arrays. I'll try to find input data on which the implementation without |
|
Or the word difference could be used as more appropiate for sets: https://en.wikipedia.org/wiki/Set_(mathematics)#Set_difference |
|
True. I thought about it some more. I close this PR since the same thing is already implemented in |
Added a generic function
subtractfor subtracting array elements and a test.This is a convenient way to solve quite often task to find the difference between sets of elements.
arrays.diffmodule is not suitable for this.