<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="321887" data-post-id="321887">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="al2o3cr" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/al2o3cr/120/3457_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  al2o3cr
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><code>optimize_boolean</code> is a red herring here - it marks the enclosed AST so that a later pass can expand it:</p>
<p><a href="https://github.com/elixir-lang/elixir/blob/8d76faa3faf508b0f67835f9d1891aa484f9acda/lib/elixir/src/elixir_expand.erl#L688-L693" class="onebox" target="_blank" rel="noopener nofollow">https://github.com/elixir-lang/elixir/blob/8d76faa3faf508b0f67835f9d1891aa484f9acda/lib/elixir/src/elixir_expand.erl#L688-L693</a></p>
<p>If the AST <em>definitely</em> has only true/false, <code>rewrite_case_clauses</code> replaces the <code>when x in [false, nil]</code> clause generated by <code>if</code> with… <code>case / end</code> with two branches <img src="https://forum.elixirforum.com/images/emoji/apple/thinking.png?v=15" title=":thinking:" class="emoji" alt=":thinking:" loading="lazy" width="20" height="20"></p>
<p>However, I don’t think it’s directly related to your situation since <code>returns_boolean</code> has a very specific list of things it’s looking for:</p>
<p><a href="https://github.com/elixir-lang/elixir/blob/8d76faa3faf508b0f67835f9d1891aa484f9acda/lib/elixir/src/elixir_utils.erl#L187-L225" class="onebox" target="_blank" rel="noopener nofollow">https://github.com/elixir-lang/elixir/blob/8d76faa3faf508b0f67835f9d1891aa484f9acda/lib/elixir/src/elixir_utils.erl#L187-L225</a></p>
<p>and <code>MapSet.member?</code> isn’t on that.</p>
<hr>
<p>A more interesting (IMO) thing to look at around performance is the shape of the BEAM code produced by the compiler. <code>@compile :S</code> is helpful as ever, given this input:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Foo2 do
  @compile :S

  def with_if(arg) do
    if arg do
      :ok
    else
      :nope
    end
  end

  def with_sim_if(arg) do
    case arg do
      false -&gt; :nope
      nil -&gt; :nope
      _ -&gt; :ok
    end
  end

  def with_case(arg) do
    case arg do
      true -&gt; :ok
      false -&gt; :nope
    end
  end

  def with_case_default(arg) do
    case arg do
      false -&gt; :nope
      _ -&gt; :ok
    end
  end

  def with_if_eq(arg) do
    if arg == false do
      :nope
    else
      :ok
    end
  end

  def with_if_when(arg) when is_boolean(arg) do
    if arg do
      :ok
    else
      :nope
    end
  end

  def with_case_when(arg) when is_boolean(arg) do
    case arg do
      true -&gt; :ok
      false -&gt; :nope
    end
  end
end
</code></pre>
<p><code>with_if</code> shows that the <code>case</code> generated by the macro translates directly to a <code>select</code> instruction:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  {label,17}.
    {select_val,{x,0},{f,19},{list,[{atom,false},{f,18},{atom,nil},{f,18}]}}.
  {label,18}.
    {move,{atom,nope},{x,0}}.
    return.
  {label,19}.
    {move,{atom,ok},{x,0}}.
    return.
</code></pre>
<p><code>with_sim_if</code> produces exactly the same instructions (other than different labels for being in a different function):</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  {label,20}.
    {line,[{location,"foo2.ex",12}]}.
    {func_info,{atom,'Elixir.Foo2'},{atom,with_sim_if},1}.
  {label,21}.
    {select_val,{x,0},{f,23},{list,[{atom,false},{f,22},{atom,nil},{f,22}]}}.
  {label,22}.
    {move,{atom,nope},{x,0}}.
    return.
  {label,23}.
    {move,{atom,ok},{x,0}}.
    return.
</code></pre>
<p>I’d expect that form to have exactly the same performance as <code>if</code> in your example.</p>
<p>The code for the <code>case</code> with explicit <code>true</code> and <code>false</code> is slightly different:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  {label,9}.
    {select_val,{x,0},{f,12},{list,[{atom,false},{f,11},{atom,true},{f,10}]}}.
  {label,10}.
    {move,{atom,ok},{x,0}}.
    return.
  {label,11}.
    {move,{atom,nope},{x,0}}.
    return.
  {label,12}.
    {line,[{location,"foo2.ex",21}]}.
    {case_end,{x,0}}.
</code></pre>
<p>This version has a <em>third</em> possible way to exit, if <code>arg</code> isn’t <code>true</code> or <code>false</code>.</p>
<p>I suspect this may cause the performance difference - maybe an optimization in the JIT for simple branches?</p>
<p>There are some other interesting variations:</p>
<ul>
<li>
<p><code>with_case_default</code> uses <code>_</code> instead of true, so there’s no “third exit”. It produces very different instructions:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">{label,14}.
  {test,is_eq_exact,{f,15},[{x,0},{atom,false}]}.
  {move,{atom,nope},{x,0}}.
  return.
{label,15}.
  {move,{atom,ok},{x,0}}.
  return.
</code></pre>
<p>I suspect this is competitively fast, if not faster than others.</p>
</li>
<li>
<p><code>with_if_eq</code> shows the <code>optimize_boolean</code> machinery doing its thing - it optimizes to the same instructions as <code>with_case_default</code>! Since the compiler knows <code>==</code> cannot return <code>nil</code>, that part of the check has been removed:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">{label,25}.
  {test,is_eq_exact,{f,26},[{x,0},{atom,false}]}.
  {move,{atom,nope},{x,0}}.
  return.
{label,26}.
  {move,{atom,ok},{x,0}}.
  return.
</code></pre>
<p>I’d expect this to perform identically to the <code>with_case_default</code> form.</p>
</li>
<li>
<p><code>with_case_when</code> and <code>with_if_when</code> supply the compiler with type information via an <code>is_boolean</code> guard, so they both produce identical instructions:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">{label,17}.
  {select_val,{x,0},{f,16},{list,[{atom,false},{f,19},{atom,true},{f,18}]}}.
{label,18}.
  {move,{atom,ok},{x,0}}.
  return.
{label,19}.
  {move,{atom,nope},{x,0}}.
  return.
</code></pre>
</li>
</ul> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="321887" data-batch-url="/posts/batch_likers">
                        6
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-case-vs-if/44492/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-321887" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="321887"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="321929" data-post-id="321929">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="ityonemo" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/ityonemo/120/11341_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  ityonemo
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>My guess (not gonna bother checking the bytecode unless people REALLY want) is that optimize_boolean ALSO has a list of “known functions with strictly boolean output” for example, and, or (vs &amp;&amp;, ||) and is able to eliminate the nil check from the if statement.</p>
<p>Well if it doesn’t do that, it probably should.  It could probably also optimze some known stdlib functions, like Map.has_key?, etc.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="321929" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-case-vs-if/44492/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-321929" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="321929"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="322040" data-post-id="322040">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="christhekeele" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/christhekeele/120/1039_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  christhekeele
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Worth pointing out <code>MapSet.member?(map_set, element)</code> does not strictly return a boolean—it also raises if <code>map_set</code> is not a <code>%MapSet{}</code>. This is probably part of the reason why it’s not on the list. (The same holds true with <code>Map.has_key?/2</code>).</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="322040" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-case-vs-if/44492/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-322040" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="322040"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="322042" data-post-id="322042">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="warmwaffles" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/warmwaffles/120/22057_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  warmwaffles
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="ityonemo" data-post="8" data-topic="44492">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/ityonemo/48/11341_2.png" class="avatar"> ityonemo:</div>
<blockquote>
<p>Usually your conditionals are not bottlenecks and it’s easier to read.</p>
</blockquote>
</aside>
<p>Definitely this. Code is read more than it is written.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="322042" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-case-vs-if/44492/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-322042" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="322042"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="322079" data-post-id="322079">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="paulsullivanjr" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/paulsullivanjr/120/14688_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  paulsullivanjr
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Agree 100%</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="322079" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-case-vs-if/44492/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-322079" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="322079"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="322082" data-post-id="322082">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Sidi_Mohammed" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Sidi_Mohammed
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I rarely use <code>if</code>, if you have multi return values from one pattern(for example <code>case x do 1-&gt;... 2-&gt;...</code>) then go with <code>case do</code>, but if you’re dealing with many patterns that are almost booleans (for example <code>if x==1....if y ! =2</code> then <code>cond do</code> will be perfect</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="322082" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-case-vs-if/44492/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-322082" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="322082"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #16"></div>
  </section>
</div>
    <div class="postbit" id="343366" data-post-id="343366">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="stevegee1" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/stevegee1/120/34564_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  stevegee1
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hello <a class="mention" href="/u/d4no0" rel="nofollow">@D4no0</a>, I couldn’t access the linked page; has it been removed?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="343366" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-case-vs-if/44492/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-343366" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="343366"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #17"></div>
  </section>
</div>
    <div class="postbit" id="343395" data-post-id="343395">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="D4no0" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/D4no0/120/33624_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  D4no0
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>How comes? I’ve just opened the link and it works.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="343395" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-case-vs-if/44492/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-343395" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="343395"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #18"></div>
  </section>
</div>
    <div class="postbit" id="343398" data-post-id="343398">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="stevegee1" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/stevegee1/120/34564_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  stevegee1
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I could access it now. Somehow, I wasn’t able to access it.<br>
Thanks.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="343398" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-case-vs-if/44492/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-343398" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="343398"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #19"></div>
  </section>
</div>
    <div class="postbit" id="343441" data-post-id="343441">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="BartOtten" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/BartOtten/120/25440_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  BartOtten
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>If this is the case, a case could be made for if. Exception to the rule: when the else case raises. You have to try yourself.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="343441" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-case-vs-if/44492/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-343441" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="343441"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>