PageSourceSearch

http://ibeetl.com/assets/index.html-morLXri8.js

js ibeetl.com collected 2026-10-03 23:19:47 UTC 14,292 bytes, 29 lines download raw bytes

1import{_ as i,c as a,b as e,o as n}from"./app-CNefOTx1.js";const t={};function l(p,s){return n(),a("div",null,s[0]||(s[0]=[e(`<h2 id="_6-7-位计算" tabindex="-1"><a class="header-anchor" href="#_6-7-位计算"><span>6.7 位计算</span></a></h2><p>Java位运算非常高效,可以使用位运算代替部分算数运算以提高性能,比如,最常用的判断奇数</p><div class="language-plaintext line-numbers-mode" data-ext="plaintext" data-title="plaintext"><button class="copy" title="Copy code" data-copied="Copied"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span>int  a = 111;</span></span>
2<span class="line"><span>System.out.print((a &amp; 1)==1);</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div></div></div><p>乘以2或者除以2,也可以使用位运算</p><div class="language-plaintext line-numbers-mode" data-ext="plaintext" data-title="plaintext"><button class="copy" title="Copy code" data-copied="Copied"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span>int  a = 111;
2//右移1位,相当于除以2</span></span>
3<span class="line"><span>System.out.println(a1);//左移1位,相当于乘以2</span></span>
4<span class="line"><span>System.out.println(a&lt;&lt;1);</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在JAVA8的Integer里,也使用了位运算来实现int转字符串(toString)。</p><div class="language-plaintext line-numbers-mode" data-ext="plaintext" data-title="plaintext"><button class="copy" title="Copy code" data-copied="Copied"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span>//r=i-q*10 优化为如下</span></span>
5<span class="line"><span>r = i - ((q &lt;&lt; 3) + (q &lt;&lt; 1));//q=i/10,优化为如下</span></span>
6<span class="line"><span>q = (i * 52429)&gt;&gt;&gt;(16+3);</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>这里<code>(i * 52429) &gt;&gt;&gt; (16+3)</code> 相当于i*0.1000000003,因此对于i较小的数据,可以认为俩着是相等的。</p><p>对比直接使用i/10 和 (i * 52429) &gt;&gt;&gt; (16+3),性能如下</p><div class="language-plaintext line-numbers-mode" data-ext="plaintext" data-title="plaintext"><button class="copy" title="Copy code" data-copied="Copied"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span>Benchmark                   Mode  Samples  Score  Score error  Units</span></span>
7<span class="line"><span>c.i.c.c.BitTest2.bit        avgt        5  0.669        0.031  ns/op</span></span>
8<span class="line"><span>c.i.c.c.BitTest2.general    avgt        5  1.251        0.560  ns/op</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在计算机里,使用除法是相对耗时的操作,所以在Java的Integer里,巧妙使用位移代替了除法。另外一个例子是在HashMap源码里,根据hash值确定对象应该放到桶的位置</p><p>假设桶的的定义是<code>Node&lt;K,V&gt;[] tab</code> ,其长度为<code>n = tab.length</code>, 则可以使用取余来确定位置,比如</p><div class="language-plaintext line-numbers-mode" data-ext="plaintext" data-title="plaintext"><button class="copy" title="Copy code" data-copied="Copied"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span>int hash = hash(key);</span></span>
9<span class="line"><span>Node&lt;K,V first = tab0[hash%n]</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div></div></div><p>但在源码里,使用了位移操作确定位置</p><div class="language-plaintext line-numbers-mode" data-ext="plaintext" data-title="plaintext"><button class="copy" title="Copy code" data-copied="Copied"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span>Node&lt;K,V first = tab[(n - 1) &amp; (hash =  hash(key) )])</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div></div></div><p>因为HashMap中的容量都是2的幂次,这样的话2的幂-1都是11111结尾的(16-&gt;10000,15-&gt;01111),当长度一定是2^n时,<code>tab[i = (2^n - 1) &amp; hash] == tab [i=(hash%2^n)]</code></p><p>以桶长度为2^4,Hash值为99(二进制是01100011)来说,99/16=6,99%16=3.可以使用位移方式实现.即01100011右移4位,剩下的为0110,是结果6,移出的011即是余数3。因为16-1的二进制是00001111,Java通过直接(16-1)&amp;99,来保留移出的位数,从而得到高效算法</p><p>关于位运算的更多知识,可以参考 Henry S.Warren,Jr.编著的《算法心得:高效算法的奥秘》</p><p>在业务系统中,也通常通过\`位\`\`来提系统高性能,比如电商中,一个订单对象,有多个属性,可能只需要一个4字节的Int类型,就能存放。这样的性能好处是</p><ul><li>提高网络传输效率,因为需要传输的内容更少了</li><li>如果这个对象需要序列化后存储到Redis或者数据库,也能节省存储空间</li></ul><p>下面代码片段显示了一个订单对象使用位来存储其多个属性</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><button class="copy" title="Copy code" data-copied="Copied"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;">public</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;"> class</span><span style="--shiki-light:#2E8F82;--shiki-dark:#5DA994;"> OrderRequest</span><span style="--shiki-light:#999999;--shiki-dark:#666666;"> {</span></span>
10<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;">    /**</span></span>
11<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;">    * 0位表示是否测试订单,1-4位节表示用户状态,5-8位表示订单状态</span></span>
12<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;">    */</span></span>
13<span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;">    int</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A;"> s</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">;</span></span>
14<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">    </span></span>
15<span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;">    public</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;"> boolean</span><span style="--shiki-light:#59873A;--shiki-dark:#80A665;"> isTest</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(){</span></span>
16<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;">        //取出第1位的值</span></span>
17<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">        return</span><span style="--shiki-light:#999999;--shiki-dark:#666666;"> (</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">status</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;">&amp;</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91;">0b1</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">)</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;">==</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91;">1</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">;</span></span>
18<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;">    }</span></span>
19<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">    </span></span>
20<span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;">    public</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;"> int</span><span style="--shiki-light:#59873A;--shiki-dark:#80A665;"> getUserStatus</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(){</span></span>
21<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;">        // 右移1,取出1-4位的值</span></span>
22<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">        return</span><span style="--shiki-light:#999999;--shiki-dark:#666666;"> (</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">status</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;">&gt;&gt;</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91;">1</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;">&amp;</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91;">0b1111</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">);</span></span>
23<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;">    }</span></span>
24<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">    </span></span>
25<span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;">    public</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;"> int</span><span style="--shiki-light:#59873A;--shiki-dark:#80A665;"> getOrderStatus</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(){</span></span>
26<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;">        //右移5,取出5-8位的值</span></span>
27<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">        return</span><span style="--shiki-light:#999999;--shiki-dark:#666666;"> (</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">status</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;">&gt;&gt;</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91;">5</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;">&amp;</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91;">0b1111</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">);</span></span>
28<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;">    }</span></span>
29<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;">}</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div>`,22)]))}const r=i(t,[["render",l],["__file","index.html.vue"]]),h=JSON.parse('{"path":"/article/performance/microtuning_bit/","title":"性能微优化-位运算","lang":"en-US","frontmatter":{"title":"性能微优化-位运算","tags":["性能","新书"],"createTime":"2026/08/20 9:20:15","permalink":"/article/performance/microtuning_bit/","description":"6.7 位计算 Java位运算非常高效,可以使用位运算代替部分算数运算以提高性能,比如,最常用的判断奇数 乘以2或者除以2,也可以使用位运算 在JAVA8的Integer里,也使用了位运算来实现int转字符串(toString)。 这里(i * 52429) >>> (16+3) 相当于i*0.1000000003,因此对于i较小的数据,可以认为俩着是...","head":[["meta",{"property":"og:url","content":"http://ibeetl.com/article/performance/microtuning_bit/"}],["meta",{"property":"og:site_name","content":"闲大赋"}],["meta",{"property":"og:title","content":"性能微优化-位运算"}],["meta",{"property":"og:description","content":"6.7 位计算 Java位运算非常高效,可以使用位运算代替部分算数运算以提高性能,比如,最常用的判断奇数 乘以2或者除以2,也可以使用位运算 在JAVA8的Integer里,也使用了位运算来实现int转字符串(toString)。 这里(i * 52429) >>> (16+3) 相当于i*0.1000000003,因此对于i较小的数据,可以认为俩着是..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2026-08-21T06:57:39.000Z"}],["meta",{"property":"article:tag","content":"性能"}],["meta",{"property":"article:tag","content":"新书"}],["meta",{"property":"article:modified_time","content":"2026-08-21T06:57:39.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"性能微优化-位运算\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"202
296-08-21T06:57:39.000Z\\",\\"author\\":[]}"]]},"headers":[],"readingTime":{"minutes":2.55,"words":766},"git":{"updatedTime":1787295459000,"contributors":[{"name":"lijiazhi","username":"lijiazhi","email":"[email protected]","commits":1,"avatar":"https://gravatar.com/avatar/1b5114831459724ad4acc394423b4b48ecfa4a7e0659fbe07a0ce5181a1050a7?d=retro"}]},"autoDesc":true,"filePathRelative":"article/性能/bit.md","categoryList":[{"id":"92a2b5","sort":10000,"name":"article"},{"id":"afdb50","sort":10004,"name":"性能"}]}');export{r as comp,h as data};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.