Skip to content

Commit d74d4ff

Browse files
committed
change f(T::Type{...}) into f(::Type{T}) where {T<:...}
In some cases, this can lead to better performance, so do it defensively.
1 parent 78d7370 commit d74d4ff

1 file changed

Lines changed: 66 additions & 49 deletions

File tree

src/sampling.jl

Lines changed: 66 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22

33

44
# allows to call `Sampler` only when the the arg isn't a Sampler itself
5-
sampler(RNG::Type{<:AbstractRNG}, X, n::Repetition=Val(Inf)) = Sampler(RNG, X, n)
6-
sampler(RNG::Type{<:AbstractRNG}, ::Type{X}, n::Repetition=Val(Inf)) where {X} = Sampler(RNG, X, n)
7-
sampler(RNG::Type{<:AbstractRNG}, X::Sampler, n::Repetition=Val(Inf)) = X
5+
sampler(::Type{RNG}, X, n::Repetition=Val(Inf)) where {RNG<:AbstractRNG} =
6+
Sampler(RNG, X, n)
7+
8+
sampler(::Type{RNG}, ::Type{X}, n::Repetition=Val(Inf)) where {RNG<:AbstractRNG,X} =
9+
Sampler(RNG, X, n)
10+
11+
sampler(::Type{RNG}, X::Sampler, n::Repetition=Val(Inf)) where {RNG<:AbstractRNG} = X
812

913
sampler(rng::AbstractRNG, X, n::Repetition=Val(Inf)) = sampler(typeof(rng), X, n)
1014

@@ -20,7 +24,7 @@ make() = make(Float64)
2024
# rand(rng, ::SamplerType{Make0{X}}) should not be overloaded, as make(T)
2125
# has this special pass-thru Sampler defined below
2226

23-
Sampler(RNG::Type{<:AbstractRNG}, ::Make0{X}, n::Repetition) where {X} =
27+
Sampler(::Type{RNG}, ::Make0{X}, n::Repetition) where {RNG<:AbstractRNG,X} =
2428
Sampler(RNG, X, n)
2529

2630
### object: handles e.g. rand(make(1:3))
@@ -39,14 +43,15 @@ end
3943
# make(::Type) is intercepted in distribution.jl
4044
make(x) = MakeWrap{gentype(x),typeof(x)}(x)
4145

42-
Sampler(RNG::Type{<:AbstractRNG}, x::MakeWrap, n::Repetition) =
46+
Sampler(::Type{RNG}, x::MakeWrap, n::Repetition) where {RNG<:AbstractRNG} =
4347
Sampler(RNG, x.x, n)
4448

4549

4650
## Uniform
4751

48-
Sampler(RNG::Type{<:AbstractRNG}, d::Union{UniformWrap,UniformType}, n::Repetition) =
49-
Sampler(RNG, d[], n)
52+
Sampler(::Type{RNG}, d::Union{UniformWrap,UniformType}, n::Repetition
53+
) where {RNG<:AbstractRNG} =
54+
Sampler(RNG, d[], n)
5055

5156

5257
## floats
@@ -55,7 +60,7 @@ Sampler(RNG::Type{<:AbstractRNG}, d::Union{UniformWrap,UniformType}, n::Repetiti
5560

5661
for CO in (:CloseOpen01, :CloseOpen12)
5762
@eval begin
58-
Sampler(RNG::Type{<:AbstractRNG}, ::$CO{T}, n::Repetition) where {T} =
63+
Sampler(::Type{RNG}, ::$CO{T}, n::Repetition) where {RNG<:AbstractRNG,T} =
5964
Sampler(RNG, Random.$CO{T}(), n)
6065

6166
Sampler(::Type{<:AbstractRNG}, ::$CO{BigFloat}, ::Repetition) =
@@ -68,7 +73,7 @@ end
6873
# TODO: optimize for BigFloat
6974

7075
for CO = (:OpenClose01, :OpenOpen01, :CloseClose01)
71-
@eval Sampler(RNG::Type{<:AbstractRNG}, I::$CO{T}, n::Repetition) where {T} =
76+
@eval Sampler(::Type{RNG}, I::$CO{T}, n::Repetition) where {RNG<:AbstractRNG,T} =
7277
SamplerSimple(I, CloseOpen01(T))
7378
end
7479

@@ -108,7 +113,7 @@ for (CO, CO01) = (CloseOpenAB => CloseOpen01,
108113
CloseCloseAB => CloseClose01,
109114
OpenOpenAB => OpenOpen01)
110115

111-
@eval Sampler(RNG::Type{<:AbstractRNG}, d::$CO{T}, n::Repetition) where {T} =
116+
@eval Sampler(::Type{RNG}, d::$CO{T}, n::Repetition) where {RNG<:AbstractRNG,T} =
112117
SamplerTag{$CO{T}}((a=d.a, d=d.b - d.a, sp=Sampler(RNG, $CO01{T}(), n)))
113118

114119
@eval rand(rng::AbstractRNG, sp::SamplerTag{$CO{T}}) where {T} =
@@ -120,7 +125,7 @@ end
120125
rand(rng::AbstractRNG, ::SamplerTrivial{Normal01{T}}) where {T<:NormalTypes} =
121126
randn(rng, T)
122127

123-
Sampler(RNG::Type{<:AbstractRNG}, d::Normalμσ{T}, n::Repetition) where {T} =
128+
Sampler(::Type{RNG}, d::Normalμσ{T}, n::Repetition) where {RNG<:AbstractRNG,T} =
124129
SamplerSimple(d, Sampler(RNG, Normal(T), n))
125130

126131
rand(rng::AbstractRNG, sp::SamplerSimple{Normalμσ{T},<:Sampler}) where {T} =
@@ -129,7 +134,7 @@ rand(rng::AbstractRNG, sp::SamplerSimple{Normalμσ{T},<:Sampler}) where {T} =
129134
rand(rng::AbstractRNG, ::SamplerTrivial{Exponential1{T}}) where {T<:AbstractFloat} =
130135
randexp(rng, T)
131136

132-
Sampler(RNG::Type{<:AbstractRNG}, d::Exponentialθ{T}, n::Repetition) where {T} =
137+
Sampler(::Type{RNG}, d::Exponentialθ{T}, n::Repetition) where {RNG<:AbstractRNG,T} =
133138
SamplerSimple(d, Sampler(RNG, Exponential(T), n))
134139

135140
rand(rng::AbstractRNG, sp::SamplerSimple{Exponentialθ{T},<:Sampler}) where {T} =
@@ -138,7 +143,7 @@ rand(rng::AbstractRNG, sp::SamplerSimple{Exponentialθ{T},<:Sampler}) where {T}
138143

139144
## Bernoulli
140145

141-
Sampler(RNG::Type{<:AbstractRNG}, b::Bernoulli, n::Repetition) =
146+
Sampler(::Type{RNG}, b::Bernoulli, n::Repetition) where {RNG<:AbstractRNG} =
142147
SamplerTag{typeof(b)}(b.p+1.0)
143148

144149
rand(rng::AbstractRNG, sp::SamplerTag{Bernoulli{T}}) where {T} =
@@ -147,7 +152,7 @@ rand(rng::AbstractRNG, sp::SamplerTag{Bernoulli{T}}) where {T} =
147152

148153
## Categorical
149154

150-
Sampler(RNG::Type{<:AbstractRNG}, c::Categorical, n::Repetition) =
155+
Sampler(::Type{RNG}, c::Categorical, n::Repetition) where {RNG<:AbstractRNG} =
151156
SamplerSimple(c, Sampler(RNG, CloseOpen(), n))
152157

153158
# unfortunately requires @inline to avoid allocating
@@ -182,12 +187,13 @@ maketype(::Type{Pair{X,Y} where X}, x, _) where {Y} = Pair{val_gentype(x), Y}
182187
maketype(::Type{Pair{X,Y}}, _, _) where {X,Y} = Pair{X,Y}
183188

184189
maketype(::Type{Complex}, x) = Complex{val_gentype(x)}
185-
maketype(T::Type{<:Complex}, _) = T
190+
maketype(::Type{T}, _) where {T<:Complex} = T
186191

187192
maketype(::Type{Complex}, x, y) = Complex{promote_type(val_gentype(x), val_gentype(y))}
188-
maketype(T::Type{<:Complex}, _, _) = T
193+
maketype(::Type{T}, _, _) where {T<:Complex} = T
189194

190-
function Sampler(RNG::Type{<:AbstractRNG}, u::Make2{T}, n::Repetition) where T <: Union{Pair,Complex}
195+
function Sampler(::Type{RNG}, u::Make2{T}, n::Repetition
196+
) where RNG<:AbstractRNG where T <: Union{Pair,Complex}
191197
sp1 = sampler(RNG, u[1], n)
192198
sp2 = u[1] == u[2] ? sp1 : sampler(RNG, u[2], n)
193199
SamplerTag{Cont{T}}((sp1, sp2))
@@ -200,24 +206,25 @@ rand(rng::AbstractRNG, sp::SamplerTag{Cont{T}}) where {T<:Union{Pair,Complex}} =
200206
#### additional convenience methods
201207

202208
# rand(Pair{A,B}) => rand(make(Pair{A,B}, A, B))
203-
Sampler(RNG::Type{<:AbstractRNG}, ::Type{Pair{A,B}}, n::Repetition) where {A,B} =
209+
Sampler(::Type{RNG}, ::Type{Pair{A,B}}, n::Repetition) where {RNG<:AbstractRNG,A,B} =
204210
Sampler(RNG, make(Pair{A,B}, A, B), n)
205211

206212
# rand(make(Complex, x)) => rand(make(Complex, x, x))
207-
Sampler(RNG::Type{<:AbstractRNG}, u::Make1{T}, n::Repetition) where {T<:Complex} =
213+
Sampler(::Type{RNG}, u::Make1{T}, n::Repetition) where {RNG<:AbstractRNG,T<:Complex} =
208214
Sampler(RNG, make(T, u[1], u[1]), n)
209215

210216
# rand(Complex{T}) => rand(make(Complex{T}, T, T)) (redundant with implem in Random)
211-
Sampler(RNG::Type{<:AbstractRNG}, ::Type{Complex{T}}, n::Repetition) where {T<:Real} =
217+
Sampler(::Type{RNG}, ::Type{Complex{T}}, n::Repetition) where {RNG<:AbstractRNG,T<:Real} =
212218
Sampler(RNG, make(Complex{T}, T, T), n)
213219

214220

215221
### sampler for tuples
216222

217223
#### "simple scalar" (non-make) version
218224

219-
Sampler(RNG::Type{<:AbstractRNG}, ::Type{T}, n::Repetition) where {T<:Union{Tuple,NamedTuple}} =
220-
Sampler(RNG, make(T), n)
225+
Sampler(::Type{RNG}, ::Type{T}, n::Repetition
226+
) where {RNG<:AbstractRNG,T<:Union{Tuple,NamedTuple}} =
227+
Sampler(RNG, make(T), n)
221228

222229
#### make
223230

@@ -265,7 +272,7 @@ _isNTuple(::Type{T}, args...) where {T<:Tuple} =
265272
end
266273
end
267274

268-
make(T::Type{<:Tuple}, args...) = _make(T, args...)
275+
make(::Type{T}, args...) where {T<:Tuple} = _make(T, args...)
269276

270277
# make(Tuple, X, n::Integer)
271278

@@ -306,13 +313,15 @@ end
306313

307314
#### Sampler for general tuples
308315

309-
@generated function Sampler(RNG::Type{<:AbstractRNG}, c::Make1{T,X}, n::Repetition) where {T<:Tuple,X<:Tuple}
316+
@generated function Sampler(::Type{RNG}, c::Make1{T,X}, n::Repetition
317+
) where {RNG<:AbstractRNG,T<:Tuple,X<:Tuple}
310318
@assert fieldcount(T) == fieldcount(X)
311319
sps = [:(sampler(RNG, c[1][$i], n)) for i in 1:length(T.parameters)]
312320
:(SamplerTag{Cont{T}}(tuple($(sps...))))
313321
end
314322

315-
@generated function Sampler(RNG::Type{<:AbstractRNG}, ::Make0{T}, n::Repetition) where {T<:Tuple}
323+
@generated function Sampler(::Type{RNG}, ::Make0{T}, n::Repetition
324+
) where {RNG<:AbstractRNG,T<:Tuple}
316325
d = Dict{DataType,Int}()
317326
sps = []
318327
for t in T.parameters
@@ -344,7 +353,7 @@ end
344353

345354
# should catch Tuple{Integer,Integer} which is not NTuple, or even Tuple{Int,UInt}, when only one sampler was passed
346355

347-
Sampler(RNG::Type{<:AbstractRNG}, c::Make1{T,X}, n::Repetition) where {T<:Tuple,X} =
356+
Sampler(::Type{RNG}, c::Make1{T,X}, n::Repetition) where {RNG<:AbstractRNG,T<:Tuple,X} =
348357
SamplerTag{Cont{T}}(sampler(RNG, c[1], n))
349358

350359
@generated function rand(rng::AbstractRNG, sp::SamplerTag{Cont{T},S}) where {T<:Tuple,S<:Sampler}
@@ -354,7 +363,7 @@ end
354363

355364
### named tuples
356365

357-
make(T::Type{<:NamedTuple}, args...) = _make(T, args...)
366+
make(::Type{T}, args...) where {T<:NamedTuple} = _make(T, args...)
358367

359368
_make(::Type{NamedTuple{}}) = Make0{NamedTuple{}}()
360369

@@ -373,10 +382,10 @@ function _make(::Type{NamedTuple{K,V}}, X...) where {K,V}
373382
end
374383

375384
# necessary to avoid circular defintions
376-
Sampler(RNG::Type{<:AbstractRNG}, m::Make0{NamedTuple}, n::Repetition) =
385+
Sampler(::Type{RNG}, m::Make0{NamedTuple}, n::Repetition) where {RNG<:AbstractRNG} =
377386
SamplerType{NamedTuple}()
378387

379-
Sampler(RNG::Type{<:AbstractRNG}, m::Make1{T}, n::Repetition) where T <: NamedTuple =
388+
Sampler(::Type{RNG}, m::Make1{T}, n::Repetition) where {RNG<:AbstractRNG, T <: NamedTuple} =
380389
SamplerTag{Cont{T}}(Sampler(RNG, m[1] , n))
381390

382391
rand(rng::AbstractRNG, sp::SamplerType{NamedTuple{}}) = NamedTuple()
@@ -391,11 +400,11 @@ rand(rng::AbstractRNG, sp::SamplerTag{Cont{T}}) where T <: NamedTuple =
391400

392401
const SetDict = Union{AbstractSet,AbstractDict}
393402

394-
make(T::Type{<:SetDict}, X, n::Integer) = Make2{maketype(T, X, n)}(X , Int(n))
395-
make(T::Type{<:SetDict}, ::Type{X}, n::Integer) where {X} = Make2{maketype(T, X, n)}(X , Int(n))
396-
make(T::Type{<:SetDict}, n::Integer) = make(T, default_sampling(T), Int(n))
403+
make(::Type{T}, X, n::Integer) where {T<:SetDict} = Make2{maketype(T, X, n)}(X , Int(n))
404+
make(::Type{T}, ::Type{X}, n::Integer) where {T<:SetDict,X} = Make2{maketype(T, X, n)}(X , Int(n))
405+
make(::Type{T}, n::Integer) where {T<:SetDict} = make(T, default_sampling(T), Int(n))
397406

398-
Sampler(RNG::Type{<:AbstractRNG}, c::Make2{T}, n::Repetition) where {T<:SetDict} =
407+
Sampler(::Type{RNG}, c::Make2{T}, n::Repetition) where {RNG<:AbstractRNG,T<:SetDict} =
399408
SamplerTag{Cont{T}}((sp = sampler(RNG, c[1], n),
400409
len = c[2]))
401410

@@ -424,8 +433,9 @@ maketype(::Type{BitSet}, _, _) = BitSet
424433

425434
### dicts
426435

427-
maketype(D::Type{<:AbstractDict{K,V}}, _, ::Integer) where {K,V} = D
428-
maketype(D::Type{<:AbstractDict{K,V}}, ::Type, ::Integer) where {K,V} = D
436+
# K,V parameters are necessary here
437+
maketype(::Type{D}, _, ::Integer) where {K,V,D<:AbstractDict{K,V}} = D
438+
maketype(::Type{D}, ::Type, ::Integer) where {K,V,D<:AbstractDict{K,V}} = D
429439

430440
#### Dict/ImmutableDict
431441

@@ -453,19 +463,25 @@ rand(rng::AbstractRNG, sp::SamplerTag{Cont{S}}) where {S<:Base.ImmutableDict} =
453463
default_sampling(::Type{<:AbstractArray{T}}) where {T} = Uniform(T)
454464
default_sampling(::Type{<:AbstractArray}) = Uniform(Float64)
455465

456-
make(A::Type{<:AbstractArray}, X, d1::Integer, dims::Integer...) = make(A, X, Dims((d1, dims...)))
457-
make(A::Type{<:AbstractArray}, ::Type{X}, d1::Integer, dims::Integer...) where {X} = make(A, X, Dims((d1, dims...)))
466+
make(::Type{A}, X, d1::Integer, dims::Integer...) where {A<:AbstractArray} =
467+
make(A, X, Dims((d1, dims...)))
468+
469+
make(::Type{A}, ::Type{X}, d1::Integer, dims::Integer...) where {A<:AbstractArray,X} =
470+
make(A, X, Dims((d1, dims...)))
471+
472+
make(::Type{A}, dims::Dims) where {A<:AbstractArray} =
473+
make(A, default_sampling(A), dims)
458474

459-
make(A::Type{<:AbstractArray}, dims::Dims) = make(A, default_sampling(A), dims)
460-
make(A::Type{<:AbstractArray}, d1::Integer, dims::Integer...) = make(A, default_sampling(A), Dims((d1, dims...)))
475+
make(::Type{A}, d1::Integer, dims::Integer...) where {A<:AbstractArray} =
476+
make(A, default_sampling(A), Dims((d1, dims...)))
461477

462478
if VERSION < v"1.1.0"
463479
# to resolve ambiguity
464480
make(A::Type{<:AbstractArray}, X, d1::Integer) = make(A, X, Dims((d1,)))
465481
make(A::Type{<:AbstractArray}, X, d1::Integer, d2::Integer) = make(A, X, Dims((d1, d2)))
466482
end
467483

468-
Sampler(RNG::Type{<:AbstractRNG}, c::Make2{A}, n::Repetition) where {A<:AbstractArray} =
484+
Sampler(::Type{RNG}, c::Make2{A}, n::Repetition) where {RNG<:AbstractRNG,A<:AbstractArray} =
469485
SamplerTag{A}((sampler(RNG, c[1], n), c[2]))
470486

471487
rand(rng::AbstractRNG, sp::SamplerTag{A}) where {A<:AbstractArray} =
@@ -476,10 +492,10 @@ rand(rng::AbstractRNG, sp::SamplerTag{A}) where {A<:AbstractArray} =
476492

477493
# cf. inference bug https://github.com/JuliaLang/julia/issues/28762
478494
# we have to write out all combinations for getting proper inference
479-
maketype(A::Type{Array{T}}, _, ::Dims{N}) where {T, N} = Array{T, N}
480-
maketype(A::Type{Array{T,N}}, _, ::Dims{N}) where {T, N} = Array{T, N}
481-
maketype(A::Type{Array{T,N} where T}, X, ::Dims{N}) where {N} = Array{val_gentype(X), N}
482-
maketype(A::Type{Array}, X, ::Dims{N}) where {N} = Array{val_gentype(X), N}
495+
maketype(::Type{Array{T}}, _, ::Dims{N}) where {T, N} = Array{T, N}
496+
maketype(::Type{Array{T,N}}, _, ::Dims{N}) where {T, N} = Array{T, N}
497+
maketype(::Type{Array{T,N} where T}, X, ::Dims{N}) where {N} = Array{val_gentype(X), N}
498+
maketype(::Type{Array}, X, ::Dims{N}) where {N} = Array{val_gentype(X), N}
483499

484500
#### BitArray
485501

@@ -498,6 +514,7 @@ maketype(::Type{SparseVector{X}}, _, p::AbstractFloat, dims::Dims{1}) where {
498514
maketype(::Type{SparseMatrixCSC{X}}, _, p::AbstractFloat, dims::Dims{2}) where {X} = SparseMatrixCSC{X, Int}
499515

500516
# need to be explicit and split these defs in 2 (or 4) to avoid ambiguities
517+
# TODO: check that using T instead of SparseVector in the RHS doesn't have perfs issues
501518
make(T::Type{SparseVector}, X, p::AbstractFloat, d1::Integer) = make(T, X, p, Dims((d1,)))
502519
make(T::Type{SparseVector}, ::Type{X}, p::AbstractFloat, d1::Integer) where {X} = make(T, X, p, Dims((d1,)))
503520
make(T::Type{SparseMatrixCSC}, X, p::AbstractFloat, d1::Integer, d2::Integer) = make(T, X, p, Dims((d1, d2)))
@@ -510,7 +527,7 @@ make(T::Type{SparseVector}, p::AbstractFloat, dims::Dims{1}) = make(T, defaul
510527
make(T::Type{SparseMatrixCSC}, p::AbstractFloat, dims::Dims{2}) = make(T, default_sampling(T), p, dims)
511528

512529

513-
Sampler(RNG::Type{<:AbstractRNG}, c::Make3{A}, n::Repetition) where {A<:AbstractSparseArray} =
530+
Sampler(::Type{RNG}, c::Make3{A}, n::Repetition) where {RNG<:AbstractRNG,A<:AbstractSparseArray} =
514531
SamplerTag{Cont{A}}((sp = sampler(RNG, c[1], n),
515532
p = c[2],
516533
dims = c[3]))
@@ -531,7 +548,7 @@ function random_staticarrays()
531548
maketype(::Type{<:$Arr{S}} , X) where {S<:Tuple} = $Arr{S,val_gentype(X),tuple_length(S),tuple_prod(S)}
532549
maketype(::Type{<:$Arr{S,T}}, _) where {S<:Tuple,T} = $Arr{S,T,tuple_length(S),tuple_prod(S)}
533550

534-
Sampler(RNG::Type{<:AbstractRNG}, c::Make1{A}, n::Repetition) where {A<:$Arr} =
551+
Sampler(::Type{RNG}, c::Make1{A}, n::Repetition) where {RNG<:AbstractRNG,A<:$Arr} =
535552
SamplerTag{Cont{A}}(Sampler(RNG, c[1], n))
536553

537554
rand(rng::AbstractRNG, sp::SamplerTag{Cont{$Arr{S,T,N,L}}}) where {S,T,N,L} =
@@ -559,10 +576,10 @@ let b = UInt8['0':'9';'A':'Z';'a':'z'],
559576
make(::Type{String}, n::Integer, chars) = Make2{String}(Int(n), chars)
560577
make(::Type{String}, n::Integer, ::Type{C}) where {C} = Make2{String}(Int(n), C)
561578

562-
Sampler(RNG::Type{<:AbstractRNG}, ::Type{String}, n::Repetition) =
579+
Sampler(::Type{RNG}, ::Type{String}, n::Repetition) where {RNG<:AbstractRNG} =
563580
SamplerTag{Cont{String}}((RNG === MersenneTwister ? s : Sampler(RNG, b, n)) => 8)
564581

565-
function Sampler(RNG::Type{<:AbstractRNG}, c::Make2{String}, n::Repetition)
582+
function Sampler(::Type{RNG}, c::Make2{String}, n::Repetition) where {RNG<:AbstractRNG}
566583
sp = RNG === MersenneTwister && c[2] === b ?
567584
s : sampler(RNG, c[2], n)
568585
SamplerTag{Cont{String}}(sp => c[1])
@@ -583,7 +600,7 @@ pair_to_make((a, b)::Pair) =
583600

584601
pair_to_make(x) = x
585602

586-
@inline Sampler(RNG::Type{<:AbstractRNG}, p::Pair, r::Repetition) =
603+
@inline Sampler(::Type{RNG}, p::Pair, r::Repetition) where {RNG<:AbstractRNG} =
587604
Sampler(RNG, pair_to_make(p), r)
588605

589606
# nothing can be inferred when only the pair type is available

0 commit comments

Comments
 (0)