Вы могли бы избежать вложенности также с помощью чего-то подобного, это также немного быстрее, чем ваш intersects(u::DataStructures.IntSet, v::DataStructures.IntSet)
метод, из-за @inbounds
:
function intersects4(u::DataStructures.IntSet, v::DataStructures.IntSet)
ch_u, ch_v = u.bits.chunks, v.bits.chunks
for i in eachindex(length(ch_u) > length(ch_v) ? ch_u : ch_v)
@inbounds if (u.inverse && v.inverse && ~ch_u[i] & ~ch_v[i] > 0) ||
(u.inverse && ~ch_u[i] & ch_v[i] > 0) ||
(v.inverse && ch_u[i] & ~ch_v[i] > 0) ||
(ch_u[i] & ch_v[i] > 0)
return true
end
end
return false
end
Вы уверены, что есть не может быть BoundsError
, если длина ch_u
больше, чем ch_v
, а функция запускает весь l oop? Я сделал for i in eachindex(length(ch_u) > length(ch_v) ? ch_u : ch_v)
на всякий случай, потому что я не проверил вашу функцию полностью.
Отличный ответ @ Дэвид Варела (я назову его функцию intersects3
), вы можете получить даже немного быстрее, чем intersect4
выше, если убедитесь, что не будет BoundsError
и использовать @inbounds
, например:
function intersects5(u::DataStructures.IntSet, v::DataStructures.IntSet)
op_u(x) = u.inverse ? ~x : x
op_v(x) = v.inverse ? ~x : x
ch_u, ch_v = u.bits.chunks, v.bits.chunks
for i in eachindex(length(ch_u) > length(ch_v) ? ch_u : ch_v)
@inbounds if op_u(ch_u[i]) & op_v(ch_v[i]) > 0
return true
end
end
return false
end
julia> begin
@btime intersects($x3, $y3) # nested ifs and bound checks
@btime intersects2($x3, $y3) # with non inline-able ops
@btime intersects3($x3, $y3) # David's improvement
@btime intersects4($x3, $y3) # without ifs and with @inbounds
@btime intersects5($x3, $y3) # David's improvement with @inbounds
end
7.184 ns (0 allocations: 0 bytes)
87.633 ns (5 allocations: 80 bytes)
6.500 ns (0 allocations: 0 bytes)
3.763 ns (0 allocations: 0 bytes)
3.079 ns (0 allocations: 0 bytes)
Также в вашем коде:
op_u = if u.inverse x -> ~x else x -> x end
Вы могли бы также сделать:
op_u = u.inverse ? (~) : identity
Поскольку оператор ~
является просто функцией, а функция identity
уже существует, в любом случае, ответ Дэвида лучше (потому что это тоже не будет встроенным), и intersects5
- самый быстрый и краткий из всех, просто хотел упомянуть об этом.