Julia: specialization on function argument not occuring as expected

Created on 28 Oct 2016  路  7Comments  路  Source: JuliaLang/julia

julia> VERSION
v"0.6.0-dev.1079"

julia> notricks(f, x) = broadcast(f, x)
notricks (generic function with 1 method)

julia> forcespec{TF}(f::TF, x) = broadcast(f, x)
forcespec (generic function with 1 method)

julia> x = rand(10^2);

julia> using BenchmarkTools

julia> @benchmark notricks($abs, $x)
BenchmarkTools.Trial:
  samples:          10000
  evals/sample:     1
  time tolerance:   5.00%
  memory tolerance: 1.00%
  memory estimate:  1.91 kb
  allocs estimate:  28
  minimum time:     19.00 渭s (0.00% GC)
  median time:      20.26 渭s (0.00% GC)
  mean time:        22.96 渭s (0.00% GC)
  maximum time:     295.82 渭s (0.00% GC)

julia> @benchmark forcespec($abs, $x)
BenchmarkTools.Trial:
  samples:          10000
  evals/sample:     849
  time tolerance:   5.00%
  memory tolerance: 1.00%
  memory estimate:  912.00 bytes
  allocs estimate:  2
  minimum time:     146.00 ns (0.00% GC)
  median time:      157.00 ns (0.00% GC)
  mean time:        201.21 ns (14.08% GC)
  maximum time:     1.63 渭s (82.76% GC)

See https://github.com/JuliaLang/julia/pull/18975#discussion_r84537865 for the original discussion and ref. #19065. Best!

doc

Most helpful comment

Re-opening this as a doc issue. It doesn't seem documented that higher-order function specialization works this way, and it seems pretty crucial to explain.

For any other abstract argument type, like Integer, a specialized version gets compiled when a concretely typed argument is passed, so I find it surprising that Function is handled differently.

All 7 comments

This is working as intended and as required to ensure compile times are reasonable

Cheers, closing then. Thanks!

Re-opening this as a doc issue. It doesn't seem documented that higher-order function specialization works this way, and it seems pretty crucial to explain.

For any other abstract argument type, like Integer, a specialized version gets compiled when a concretely typed argument is passed, so I find it surprising that Function is handled differently.

Also, doesn't #8974 mean that f{TF}(f::TF, x)=... and f(f, x)=... their signature type will become identical? See e.g. https://github.com/JuliaLang/julia/issues/19159#issuecomment-257169928. Then both definitions would need to have identical results.

no. #8974 only says that you'll get a warning when you define two methods whose signatures cover exactly the same set of types. it doesn't require that every method do the same thing.

Still, it would make this even more confusing. If this is needed, maybe being more explicit would be better?

This is now documented in the performance tips.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

felixrehren picture felixrehren  路  3Comments

manor picture manor  路  3Comments

omus picture omus  路  3Comments

omus picture omus  路  3Comments

StefanKarpinski picture StefanKarpinski  路  3Comments