Stream: helpdesk (published)

Topic: comprehension without allocating


view this post on Zulip Filippos Christou (Jan 12 2023 at 15:16):

A comprehension by default creates an vector.
Sometimes though I use comprehension as an one-line mutating procedure.
e.g.:

a = collect(1:100)

# my one-liner mutating comprehension
deletespec!(a,v) = [deleteat!(a, x) for x in v];

Clearly here, I am not interested in the result.
I just want the mutating operation to happen.

Calling it will return a vector, which means something got allocated, that I didn't really need

julia> deletespec!(a, [1,2,3])
[[2, 4, 6, 7, 8, 9, 10, 11, 12, 13  …  91, 92, 93, 94, 95, 96, 97, 98, 99, 100], [2, 4, 6, 7, 8, 9, 10, 11, 12, 13  …  91, 92, 93, 94, 95, 96, 97, 98, 99, 100], [2, 4, 6, 7, 8, 9, 10, 11, 12, 13  …  91, 92, 93, 94, 95, 96, 97, 98, 99, 100]]

Is there a way to produce comprehensions that return nothing, i.e. allocate nothing ?
Should I even worry about this performance-wise ?

PS I know what I am doing to delete multiple indices is wrong and there are better ways to do that, but please don't focus on this.

view this post on Zulip Filippos Christou (Jan 12 2023 at 15:16):

A comprehension by default creates an vector.
Sometimes though I use comprehension as an one-line mutating procedure.
e.g.:

a = collect(1:100)

# my one-liner mutating comprehension
deletespec!(a,v) = [deleteat!(a, x) for x in v];

Clearly here, I am not interested in the result.
I just want the mutating operation to happen.

Calling it will return a vector, which means something got allocated, that I didn't really need

julia> deletespec!(a, [1,2,3])
[[2, 4, 6, 7, 8, 9, 10, 11, 12, 13  …  91, 92, 93, 94, 95, 96, 97, 98, 99, 100], [2, 4, 6, 7, 8, 9, 10, 11, 12, 13  …  91, 92, 93, 94, 95, 96, 97, 98, 99, 100], [2, 4, 6, 7, 8, 9, 10, 11, 12, 13  …  91, 92, 93, 94, 95, 96, 97, 98, 99, 100]]

Is there a way to produce comprehensions that return nothing, i.e. allocate nothing ?
Should I even worry about this performance-wise ?

PS I know what I am doing to delete multiple indices is wrong and there are better ways to do that, but please don't focus on this.

view this post on Zulip mbaz (Jan 12 2023 at 15:18):

Would a generator work here?

view this post on Zulip Filippos Christou (Jan 12 2023 at 15:31):

you mean writing (deleteat!(a, x) for x in v) instead of [deleteat!(a, x) for x in v]. It would work but again it feels like there is some effort going somewhere (e.g. constructing the generator) which is unneeded.

view this post on Zulip Filippos Christou (Jan 12 2023 at 15:32):

wait no, it wouldn't work.

view this post on Zulip Filippos Christou (Jan 12 2023 at 15:33):

the mutation will happen only when I start iterating the elements of the generator.

view this post on Zulip Brian Chen (Jan 12 2023 at 15:59):

Why not use foreach?

view this post on Zulip Filippos Christou (Jan 12 2023 at 16:09):

Yes, this is a good suggestion.. However nested foreach will get ugly. Comprehensions are easier to follow in that regard..

view this post on Zulip Gunnar Farnebäck (Jan 12 2023 at 18:58):

Nested foreach using the do construction shouldn't be that ugly, or am I missing something?

view this post on Zulip Mason Protter (Jan 12 2023 at 19:43):

Nested list comprehensions would also get pretty ugly pretty fast


Last updated: Oct 02 2023 at 04:34 UTC