As an old C programmer, I use lots of asserts in my code. Now I want to globally switch them off to speed things up. What is the best practice way to do that?
Although it would be nice to have this feature, the need for @assert
s in your code can be reduced by defining and dispatching on your own types. For example, suppose you have a function foo(t::TimeType) = t
, but you only want to accept times that are a multiple of five minutes. You can create a new type with this requirement:
using Dates
struct FiveMinuteMultiple
t::DateTime
function FiveMinuteMultiple(y, m, d, h, mi)
if mi%5 != 0
throw(DomainError(m, "the minute argument must be a multiple of 5"))
end
new(DateTime(y, m, d, h, mi))
end
end
Now you literally can't create a FiveMinuteMultiple
that is not a multiple of five minutes:
julia> t = FiveMinuteMultiple(2016, 7, 15, 4, 23)
ERROR: DomainError with 7:
the minute argument must be a multiple of 5
Stacktrace:
[1] FiveMinuteMultiple(::Int64, ::Int64, ::Int64, ::Int64, ::Int64) at ./REPL[2]:5
[2] top-level scope at none:0
julia> t = FiveMinuteMultiple(2016, 7, 15, 4, 25)
FiveMinuteMultiple(2016-07-15T04:25:00)
So if you now define foo(t::FiveMinuteMultiple) = t
, you no longer need an @assert
to verify that the argument is a time that is a multiple of five minutes. Sure, you still have to pay the cost of argument checking when you construct the FiveMinuteMultiple
, but unless it's a hot inner loop you probably want that additional data validation anyways.
Advantages:
foo(t::FiveMinuteMultiple)
, bar(t::FiveMinuteMultiple)
, and baz(t::FiveMinuteMultiple)
.Disadvantages:
FiveMinuteMultiple
you may need to forward methods such as day
, hour
, etc, to the t
field of the struct.There is no built-in option / command line flag to disable @assert
s globally, yet(!).
For now, you can define a @myassert
macro which, depending on a global switch, is a no-op or a regular @assert
:
asserting() = false # when set to true, this will enable all `@myassert`s
macro mayassert(test)
esc(:(if $(@__MODULE__).asserting()
@assert($test)
end))
end
f(x) = @mayassert x < 2
(taken from https://discourse.julialang.org/t/assert-alternatives/24775/14)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With