<p dir="auto">First discussed here: <a href="https://discourse.julialang.org/t/unnecessary-where-t-causes-huge-performance-drop/31078" rel="nofollow">https://discourse.julialang.org/t/unnecessary-where-t-causes-huge-performance-drop/31078</a></p>
<p dir="auto">Given the following functions in a Julia 1.3rc4 session:</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function f1(x) where {T}
    return x*2
end

function f2(x)
    return x*2
end

function f3(::Type{T}, x) where {T}
    return x*2
end"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-en">f1</span>(x) <span class="pl-k">where</span> {T}
    <span class="pl-k">return</span> x<span class="pl-k">*</span><span class="pl-c1">2</span>
<span class="pl-k">end</span>

<span class="pl-k">function</span> <span class="pl-en">f2</span>(x)
    <span class="pl-k">return</span> x<span class="pl-k">*</span><span class="pl-c1">2</span>
<span class="pl-k">end</span>

<span class="pl-k">function</span> <span class="pl-en">f3</span>(<span class="pl-k">::</span><span class="pl-c1">Type{T}</span>, x) <span class="pl-k">where</span> {T}
    <span class="pl-k">return</span> x<span class="pl-k">*</span><span class="pl-c1">2</span>
<span class="pl-k">end</span></pre></div>
<p dir="auto">I'd assume that all of them would generate the same machine code for the same <code class="notranslate">x</code>. This is however not the case:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="@btime f1(1)
  10.825 ns (0 allocations: 0 bytes)
2

@btime f2(1)
  0.017 ns (0 allocations: 0 bytes)
2

@btime f3(Bool, 1)
  0.017 ns (0 allocations: 0 bytes)"><pre class="notranslate"><code class="notranslate">@btime f1(1)
  10.825 ns (0 allocations: 0 bytes)
2

@btime f2(1)
  0.017 ns (0 allocations: 0 bytes)
2

@btime f3(Bool, 1)
  0.017 ns (0 allocations: 0 bytes)
</code></pre></div>
<p dir="auto">For both <code class="notranslate">f2</code> and <code class="notranslate">f3</code> the constant folding worked, but <code class="notranslate">f1</code> does something differently. I also tried it using broadcasting to trick the constant folding:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="a = rand(1000);
@btime f1.($a);
  14.736 μs (2001 allocations: 39.19 KiB)

@btime f2.($a);
  471.755 ns (1 allocation: 7.94 KiB)

@btime f3.(Bool, $a);
  445.223 ns (1 allocation: 7.94 KiB)"><pre class="notranslate"><code class="notranslate">a = rand(1000);
@btime f1.($a);
  14.736 μs (2001 allocations: 39.19 KiB)

@btime f2.($a);
  471.755 ns (1 allocation: 7.94 KiB)

@btime f3.(Bool, $a);
  445.223 ns (1 allocation: 7.94 KiB)
</code></pre></div>
<p dir="auto">There are a lot of allocations which I do not understand. Is this some kind of a lowering bug?</p>
<p dir="auto">Update: sorry, I did a silly mistake, v0.7 of Julia shows the same behaviour</p>
<p dir="auto">Under some circumstances, having an unused typevar in a method definition causes the method to unexpectedly allocate and perform poorly. For example:</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="julia&gt; function foo(y::T) where {N, T}
         1.0 * y
       end
foo (generic function with 1 method)

julia&gt; using BenchmarkTools
[ Info: Recompiling stale cache file /home/BOSDYN/rdeits/.julia/compiled/v1.0/BenchmarkTools/ZXPQo.ji for BenchmarkTools [6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf]

julia&gt; @btime foo($(1))
  13.938 ns (1 allocation: 16 bytes)
1.0"><pre class="notranslate">julia<span class="pl-k">&gt;</span> <span class="pl-k">function</span> <span class="pl-en">foo</span>(y<span class="pl-k">::</span><span class="pl-c1">T</span>) <span class="pl-k">where</span> {N, T}
         <span class="pl-c1">1.0</span> <span class="pl-k">*</span> y
       <span class="pl-k">end</span>
foo (generic <span class="pl-k">function</span> with <span class="pl-c1">1</span> method)

julia<span class="pl-k">&gt;</span> <span class="pl-k">using</span> BenchmarkTools
[ Info<span class="pl-k">:</span> Recompiling stale cache file <span class="pl-k">/</span>home<span class="pl-k">/</span>BOSDYN<span class="pl-k">/</span>rdeits<span class="pl-k">/</span><span class="pl-k">.</span>julia<span class="pl-k">/</span>compiled<span class="pl-k">/</span>v1.<span class="pl-c1">0</span><span class="pl-k">/</span>BenchmarkTools<span class="pl-k">/</span>ZXPQo<span class="pl-k">.</span>ji <span class="pl-k">for</span> BenchmarkTools [<span class="pl-c1">6e4</span>b80f9<span class="pl-k">-</span>dd63<span class="pl-k">-</span><span class="pl-c1">53</span>aa<span class="pl-k">-</span><span class="pl-c1">95</span>a3<span class="pl-k">-</span><span class="pl-c1">0</span>cdb28fa8baf]

julia<span class="pl-k">&gt;</span> <span class="pl-c1">@btime</span> <span class="pl-c1">foo</span>(<span class="pl-k">$</span>(<span class="pl-c1">1</span>))
  <span class="pl-c1">13.938</span> ns (<span class="pl-c1">1</span> allocation<span class="pl-k">:</span> <span class="pl-c1">16</span> bytes)
<span class="pl-c1">1.0</span></pre></div>
<p dir="auto">where the <code class="notranslate">N</code> parameter is unused. Removing that parameter fixes the problem:</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="julia&gt; function foo(y::T) where {T}
         1.0 * y
       end
foo (generic function with 1 method)

julia&gt; @btime foo($(1))
  1.239 ns (0 allocations: 0 bytes)
1.0"><pre class="notranslate">julia<span class="pl-k">&gt;</span> <span class="pl-k">function</span> <span class="pl-en">foo</span>(y<span class="pl-k">::</span><span class="pl-c1">T</span>) <span class="pl-k">where</span> {T}
         <span class="pl-c1">1.0</span> <span class="pl-k">*</span> y
       <span class="pl-k">end</span>
foo (generic <span class="pl-k">function</span> with <span class="pl-c1">1</span> method)

julia<span class="pl-k">&gt;</span> <span class="pl-c1">@btime</span> <span class="pl-c1">foo</span>(<span class="pl-k">$</span>(<span class="pl-c1">1</span>))
  <span class="pl-c1">1.239</span> ns (<span class="pl-c1">0</span> allocations<span class="pl-k">:</span> <span class="pl-c1">0</span> bytes)
<span class="pl-c1">1.0</span></pre></div>
<p dir="auto">Is this and expected performance issue? I've observed it with Julia 1.0 and the latest nightly build.</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="julia&gt; versioninfo()
Julia Version 1.0.1-pre.171
Commit 398d87829d (2018-09-26 22:52 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Xeon(R) CPU E3-1535M v6 @ 3.10GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.0 (ORCJIT, skylake)"><pre class="notranslate">julia<span class="pl-k">&gt;</span> <span class="pl-c1">versioninfo</span>()
Julia Version <span class="pl-c1">1.0</span>.<span class="pl-c1">1</span><span class="pl-k">-</span>pre.<span class="pl-c1">171</span>
Commit <span class="pl-c1">398</span>d87829d (<span class="pl-c1">2018</span><span class="pl-k">-</span><span class="pl-c1">09</span><span class="pl-k">-</span><span class="pl-c1">26</span> <span class="pl-c1">22</span><span class="pl-k">:</span><span class="pl-c1">52</span> UTC)
Platform Info<span class="pl-k">:</span>
  OS<span class="pl-k">:</span> Linux (x86_64<span class="pl-k">-</span>pc<span class="pl-k">-</span>linux<span class="pl-k">-</span>gnu)
  CPU<span class="pl-k">:</span> <span class="pl-c1">Intel</span>(R) <span class="pl-c1">Xeon</span>(R) CPU E3<span class="pl-k">-</span><span class="pl-c1">1535</span>M v6 @ <span class="pl-c1">3.10</span>GHz
  WORD_SIZE<span class="pl-k">:</span> <span class="pl-c1">64</span>
  LIBM<span class="pl-k">:</span> libopenlibm
  LLVM<span class="pl-k">:</span> libLLVM<span class="pl-k">-</span><span class="pl-c1">6.0</span>.<span class="pl-c1">0</span> (ORCJIT, skylake)</pre></div>