CINXE.COM
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta http-equiv="x-ua-compatible" content="ie=edge"/><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/><meta name="generator" content="Gatsby 5.13.4"/><meta name="description" content="最近、筆者はRaBitQという新しい近似最近傍探索アルゴリズムを使ったさまざまな試みを行っています。このアルゴリズムを提案した論文の著者はすでにC++実装を提供しており、実行速度はかなり速いです。筆…" data-gatsby-head="true"/><meta property="og:title" content="アルゴリズムのパフォーマンスを段階的に改善する | POSTD" data-gatsby-head="true"/><meta property="og:site_name" content="POSTD | ニジボックスが運営するエンジニアに向けたキュレーションメディア" data-gatsby-head="true"/><meta property="og:url" content="https://postd.cc/rabitq-bench/" data-gatsby-head="true"/><meta property="og:image" content="https://postd.cc/static/4ed810b3d112d772c2cc124b5e8fba5d/mv.png" data-gatsby-head="true"/><meta name="msapplication-TileColor" content="#ffffff" data-gatsby-head="true"/><meta name="msapplication-TileImage" content="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJAAAACQCAIAAABoJHXvAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3NpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDplMTE0N2M1NS1hYmIzLTQwN2YtOGRmMy0zNzRhM2JkNGRkYmYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NjIwMEM5N0ZGMkM4MTFFMzgxMjM5NDExNDlEMUM0REMiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NjIwMEM5N0VGMkM4MTFFMzgxMjM5NDExNDlEMUM0REMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6YTBhOWE0NTEtYTc4OC00Y2ZjLTgyYWYtNGFjMDIzY2UwNzU0IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOmUxMTQ3YzU1LWFiYjMtNDA3Zi04ZGYzLTM3NGEzYmQ0ZGRiZiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpKUn6UAAAR3SURBVHja7Ny/Szp9AMDxJzPS1AyDDCQxK+nn0KAVYVANBWKWSEtTEf0JNQVNbUFjS1NDWEMR1VQ29IPmcigKJbChyCIDKYR8Dr4Pz/B9HrzTvnpnvd9DUHzqrnt13ue8u0rS6fRfVDyVAAYYAUaAAUaAEWCAEWAEGGAEGAEGGAFGgAFGgBFggBFgBBhgBBgBBhgBRoABBhhgBBgVCKykpOS3r/x3iVLGiH5Lbmk0Gq1WazKZLBaL3W5vamrq7Ozs6empqqoCTIlg/5tKpXK5XKOjo36/XyBUllg6z0lZYg5rVbDt09/fv7m5mUql0soIMEk5HI5gMPj5+QlYcYD9qru7OxwOA1Y0YELl5eWLi4sy7mqA5ZLP50skErKAMUvMsY6OjoODg5qaGqb1xQEm1NraGgqFzGYzYF8Fq6io8Hg8UlZPmK8/Pz9Ho9FYLJbDphD2s+PjY6PRyHnYl45hVqs12/WMx+M7OzvT09MmkymrDej1egs5BwHs95LJ5MrKivATpJstLS0BJhvYv2xzc3NqtVriG5LX19eAyQn2q6Ojo+rqailmQ0NDgMkPJnR1dVVbWyvF7PDwEDD5wYQuLi70er0o2MDAAGCKABMKBoNSTmBubm7yvT1VXMOV0vj4eCAQED1BWl1d5TxMEXuYkDAPFJ002u129jCl5HA4/H5/5jGRSESYpOR1NQDLosnJSdExJycngCmlwcFBnU6Xeczl5SVgSqmsrKy3tzfzGOFQB5iCam9vzzzg9vYWMAVls9kyD3h6egJMQYle+np9fQVMQYmeiqlUKsAU1NvbW+YBBoMBMAX1+Pj4xddMwAqa6Kw93/fkAJZdZ2dnmQe0tLQAppSEc6xoNApY0bS2tiY6pqurK6/r8D3vS7RarXd3d3/2F0kmk3a7/eHhIcMYrVYbj8eFj+xh8re8vJxZS8jj8eRV65+/ZS5gSrkVR6PRiG7M3d1dLmDKXyKRCAQC7+/vmYfV1dUNDw/ne2UAEz90eb3ecDgsOnJ2dra0tDTvK8RLYoZisZjT6ZSyGevr6z8+PrjNTU6w9fV16Y9/bW1tceevbGChUMjtdkt/lZqYmOBhiEKDCXOK09PT+fn55ubmrI4pjY2NwrkXj8wW6IE+IWFz39/fRyKRVCqV7W9nNBrPz8+zNeadDnnS6/V7e3t9fX2FXChgOVZZWbm/vy96ExVgigATjlvb29ttbW0yLPtbTjry2tjY2MvLS1qmAMsis9m8sbGRljXApB6xFhYW5PrvN99/Wv9nD1czMzNTU1MSH3Zm0iEPWENDg8/nGxkZcbvd+b7VELAsUqvVBoNBp9NZLBabzWa3251Op8vlEj5V5tWDYgX7sQEGGGCAEWCAAQYYAQYYYIAB9h3AlHBPgJTyvj0BAwwwwAADDDDAfgwYAQYYYIARYIABBljxTtmZ1gMGGGCAAQYYYIDRD53WE2CAEWAEGAEGGAFGgAFGgBFggBFgBBhgBBgBBhgBRoABRoARYIARYAQYYAQYAQYYFUt/CzAAPkGUpXqQ7qgAAAAASUVORK5CYII=" data-gatsby-head="true"/><meta name="apple-mobile-web-app-title" content="POSTD" data-gatsby-head="true"/><style data-href="/styles.13c58abb04fb026633da.css" data-identity="gatsby-global-css">code[class*=language-],pre[class*=language-]{word-wrap:normal;background:none;color:#fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;-webkit-hyphens:none;hyphens:none;line-height:1.5;tab-size:4;text-align:left;text-shadow:0 -.1em .2em #000;white-space:pre;word-break:normal;word-spacing:normal}:not(pre)>code[class*=language-],pre[class*=language-]{background:#141414}pre[class*=language-]{border:.3em solid #545454;border-radius:.5em;box-shadow:inset 1px 1px .5em #000;margin:.5em 0;overflow:auto;padding:1em}pre[class*=language-]::selection{background:#27292a}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{background:hsla(0,0%,93%,.15);text-shadow:none}:not(pre)>code[class*=language-]{border:.13em solid #545454;border-radius:.3em;box-shadow:inset 1px 1px .3em -.1em #000;padding:.15em .2em .05em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#787878}.token.namespace,.token.punctuation{opacity:.7}.token.boolean,.token.deleted,.token.number,.token.tag{color:#cf694a}.token.builtin,.token.constant,.token.keyword,.token.property,.token.selector,.token.symbol{color:#f9ee9a}.language-css .token.string,.style .token.string,.token.attr-name,.token.attr-value,.token.char,.token.entity,.token.inserted,.token.operator,.token.string,.token.url,.token.variable{color:#919e6b}.token.atrule{color:#7386a5}.token.important,.token.regex{color:#e9c163}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.language-markup .token.attr-name,.language-markup .token.punctuation,.language-markup .token.tag{color:#ad895c}.token{position:relative;z-index:1}.line-highlight.line-highlight{background:rgba(84,84,84,.25);background:linear-gradient(90deg,rgba(84,84,84,.1) 70%,rgba(84,84,84,0));border-bottom:1px dashed #545454;border-top:1px dashed #545454;margin-top:.75em;z-index:0}.line-highlight.line-highlight:before,.line-highlight.line-highlight[data-end]:after{background-color:#8794a6;color:#f5f2f0}pre[class*=language-].line-numbers{counter-reset:linenumber;padding-left:3.8em;position:relative}pre[class*=language-].line-numbers>code{position:relative;white-space:inherit}.line-numbers .line-numbers-rows{border-right:1px solid #999;font-size:100%;left:-3.8em;letter-spacing:-1px;pointer-events:none;position:absolute;top:0;-webkit-user-select:none;user-select:none;width:3em}.line-numbers-rows>span{counter-increment:linenumber;display:block}.line-numbers-rows>span:before{color:#999;content:counter(linenumber);display:block;padding-right:.8em;text-align:right}.admonition{margin-bottom:1em;padding:15px 30px 15px 15px}.admonition h5{margin-bottom:8px;margin-top:0;text-transform:uppercase}.admonition-icon{display:inline-block;margin-right:.2em;vertical-align:middle}.admonition-icon svg{stroke-width:0;display:inline-block;height:22px;width:22px}.admonition-content>:last-child{margin-bottom:0}.admonition{background-color:rgba(118,51,219,.1);border-left:8px solid #7633db}.admonition h5{color:#7633db}.admonition .admonition-icon svg{stroke:#7633db;fill:#7633db}.admonition-caution{background-color:rgba(230,126,34,.1);border-left:8px solid #e67e22}.admonition-caution h5{color:#e67e22}.admonition-caution .admonition-icon svg{stroke:#e67e22;fill:#e67e22}.admonition-tip{background-color:rgba(46,204,113,.1);border-left:8px solid #2ecc71}.admonition-tip h5{color:#2ecc71}.admonition-tip .admonition-icon svg{stroke:#2ecc71;fill:#2ecc71}.admonition-warning{background-color:rgba(231,76,60,.1);border-left:8px solid #e74c3c}.admonition-warning h5{color:#e74c3c}.admonition-warning .admonition-icon svg{stroke:#e74c3c;fill:#e74c3c}.admonition-important{background-color:rgba(52,152,219,.1);border-left:8px solid #3498db}.admonition-important h5{color:#3498db}.admonition-important .admonition-icon svg{stroke:#3498db;fill:#3498db}.admonition-note{background-color:rgba(241,196,15,.1);border-left:8px solid #f1c40f}.admonition-note h5{color:#f1c40f}.admonition-note .admonition-icon svg{stroke:#f1c40f;fill:#f1c40f}</style><style>.gatsby-image-wrapper{position:relative;overflow:hidden}.gatsby-image-wrapper picture.object-fit-polyfill{position:static!important}.gatsby-image-wrapper img{bottom:0;height:100%;left:0;margin:0;max-width:none;padding:0;position:absolute;right:0;top:0;width:100%;object-fit:cover}.gatsby-image-wrapper [data-main-image]{opacity:0;transform:translateZ(0);transition:opacity .25s linear;will-change:opacity}.gatsby-image-wrapper-constrained{display:inline-block;vertical-align:top}</style><noscript><style>.gatsby-image-wrapper noscript [data-main-image]{opacity:1!important}.gatsby-image-wrapper [data-placeholder-image]{opacity:0!important}</style></noscript><script type="module">const e="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;e&&document.body.addEventListener("load",(function(e){const t=e.target;if(void 0===t.dataset.mainImage)return;if(void 0===t.dataset.gatsbyImageSsr)return;let a=null,n=t;for(;null===a&&n;)void 0!==n.parentNode.dataset.gatsbyImageWrapper&&(a=n.parentNode),n=n.parentNode;const o=a.querySelector("[data-placeholder-image]"),r=new Image;r.src=t.currentSrc,r.decode().catch((()=>{})).then((()=>{t.style.opacity=1,o&&(o.style.opacity=0,o.style.transition="opacity 500ms linear")}))}),!0);</script><style data-styled="" data-styled-version="6.1.10">.eChxWj{display:none;background:transparent;border:none;appearance:none;}/*!sc*/ @media (max-width: 767px){.eChxWj{display:block;}}/*!sc*/ data-styled.g1[id="HeaderNavButton__Wrapper-sc-giz7fq-0"]{content:"eChxWj,"}/*!sc*/ .jpcQJX{width:22px;height:2px;background:#1b1b1b;transition:opacity 0.2s,transform 0.2s;}/*!sc*/ .jpcQJX:nth-child(1){transform:translateY(0) rotate(0);}/*!sc*/ .jpcQJX:nth-child(2){margin-top:6px;opacity:1;}/*!sc*/ .jpcQJX:nth-child(3){margin-top:6px;transform:translateY(0) rotate(0);}/*!sc*/ data-styled.g2[id="HeaderNavButton__Line-sc-giz7fq-1"]{content:"jpcQJX,"}/*!sc*/ .hLsmrx{display:inline;}/*!sc*/ @media (max-width: 767px){.hLsmrx{display:none;}}/*!sc*/ .kITRPe{display:none;}/*!sc*/ @media (max-width: 767px){.kITRPe{display:none;}}/*!sc*/ data-styled.g3[id="HeaderLogo__Pc-sc-128t2eb-0"]{content:"hLsmrx,kITRPe,"}/*!sc*/ .djySHL{display:none;}/*!sc*/ @media (max-width: 767px){.djySHL{display:inline;}}/*!sc*/ .iNZNRU{display:inline;}/*!sc*/ @media (max-width: 767px){.iNZNRU{display:inline;}}/*!sc*/ data-styled.g4[id="HeaderLogo__Sp-sc-128t2eb-1"]{content:"djySHL,iNZNRU,"}/*!sc*/ .fcSJox{line-height:1.6;color:#666;font-size:12px;font-weight:bold;white-space:nowrap;}/*!sc*/ @media (max-width: 767px){.fcSJox{font-size:10px;font-weight:normal;}}/*!sc*/ .iQWsBp{line-height:1.6;color:#666;font-size:10px;font-weight:normal;white-space:nowrap;}/*!sc*/ @media (max-width: 767px){.iQWsBp{font-size:10px;font-weight:normal;}}/*!sc*/ data-styled.g5[id="HeaderDescription__Text-sc-clsdq0-0"]{content:"fcSJox,iQWsBp,"}/*!sc*/ .icgTxN{display:flex;align-items:center;}/*!sc*/ data-styled.g6[id="HeaderLeftSide__Wrapper-sc-151me4h-0"]{content:"icgTxN,"}/*!sc*/ .iteQnd{margin-left:20px;}/*!sc*/ data-styled.g7[id="HeaderLeftSide__DescriptionWrapper-sc-151me4h-1"]{content:"iteQnd,"}/*!sc*/ .egfLUA:not(:first-child){margin-left:20px;}/*!sc*/ data-styled.g8[id="HeaderIconLink__ExternalLink-sc-nsmdxc-0"]{content:"egfLUA,"}/*!sc*/ .hyUZWO{display:flex;}/*!sc*/ data-styled.g9[id="HeaderIcons__Wrapper-sc-fl6baq-0"]{content:"hyUZWO,"}/*!sc*/ .dOgXOf{display:block;font-size:11px;color:#767676;}/*!sc*/ data-styled.g10[id="Copyright__Text-sc-1yjjwtv-0"]{content:"dOgXOf,"}/*!sc*/ .kUpMwN{text-align:center;}/*!sc*/ data-styled.g11[id="HeaderCorpInfo__Wrapper-sc-1k2ubzo-0"]{content:"kUpMwN,"}/*!sc*/ .kHPENY{margin-top:12px;}/*!sc*/ data-styled.g12[id="HeaderCorpInfo__CopyrightWrapper-sc-1k2ubzo-1"]{content:"kHPENY,"}/*!sc*/ .gPnRce{font-size:14px;font-weight:bold;color:inherit;}/*!sc*/ @media (max-width: 767px){.gPnRce{font-size:13px;}}/*!sc*/ .cuVxce{font-size:14px;font-weight:bold;color:#fff;}/*!sc*/ @media (max-width: 767px){.cuVxce{font-size:13px;}}/*!sc*/ data-styled.g13[id="NavLinkHeading__Text-sc-9g8hpt-0"]{content:"gPnRce,cuVxce,"}/*!sc*/ .cZIIUC{font-size:13px;color:inherit;text-decoration:none;}/*!sc*/ @media (max-width: 767px){.cZIIUC{font-size:12px;}}/*!sc*/ .iHRgOu{font-size:13px;color:#fff;text-decoration:none;}/*!sc*/ @media (max-width: 767px){.iHRgOu{font-size:12px;}}/*!sc*/ data-styled.g14[id="NavLink__StyledLink-sc-12swpe6-0"]{content:"cZIIUC,iHRgOu,"}/*!sc*/ .ORlYd{font-size:13px;color:inherit;text-decoration:none;}/*!sc*/ @media (max-width: 767px){.ORlYd{font-size:12px;}}/*!sc*/ .fWpGyB{font-size:13px;color:#fff;text-decoration:none;}/*!sc*/ @media (max-width: 767px){.fWpGyB{font-size:12px;}}/*!sc*/ data-styled.g15[id="NavLink__ExternalLink-sc-12swpe6-1"]{content:"ORlYd,fWpGyB,"}/*!sc*/ .kjavfV{display:inline-block;padding:8px 12px;border:1px solid #ddd;border-radius:30px;}/*!sc*/ data-styled.g16[id="NavLink__TagLink-sc-12swpe6-2"]{content:"kjavfV,"}/*!sc*/ .jYwaN{display:inline-block;}/*!sc*/ .jYwaN::after{display:inline-block;width:7px;height:7px;margin-left:7px;content:"";border-top:2px solid #1b1b1b;border-right:2px solid #1b1b1b;transform:rotate(45deg);}/*!sc*/ .fXlqex{display:inline-block;}/*!sc*/ .fXlqex::after{display:inline-block;width:7px;height:7px;margin-left:7px;content:"";border-top:2px solid #fff;border-right:2px solid #fff;transform:rotate(45deg);}/*!sc*/ data-styled.g17[id="NavLink__MoreLink-sc-12swpe6-3"]{content:"jYwaN,fXlqex,"}/*!sc*/ .bubIBK:not(:first-child){margin-top:40px;}/*!sc*/ data-styled.g18[id="HeaderNavLinks__Wrapper-sc-df9m31-0"]{content:"bubIBK,"}/*!sc*/ .kGEgB{display:flex;flex-wrap:wrap;justify-content:space-between;}/*!sc*/ data-styled.g19[id="HeaderNavLinks__LinkList-sc-df9m31-1"]{content:"kGEgB,"}/*!sc*/ .kJcagp{display:flex;flex-wrap:wrap;margin-left:-10px;}/*!sc*/ data-styled.g20[id="HeaderNavLinks__TagLinkList-sc-df9m31-2"]{content:"kJcagp,"}/*!sc*/ .hWqcld{flex-basis:50%;margin-top:17px;}/*!sc*/ data-styled.g21[id="HeaderNavLinks__LinkItem-sc-df9m31-3"]{content:"hWqcld,"}/*!sc*/ .pbhGK{margin:17px 0 0 10px;}/*!sc*/ data-styled.g22[id="HeaderNavLinks__TagLinkItem-sc-df9m31-4"]{content:"pbhGK,"}/*!sc*/ .bRPEEh{margin-top:20px;}/*!sc*/ data-styled.g23[id="HeaderNavLinks__MoreLinkWrapper-sc-df9m31-5"]{content:"bRPEEh,"}/*!sc*/ .hUVZkP{position:fixed;z-index:50;display:none;width:100vw;height:100vh;padding:104px 20px 20px;overflow-y:scroll;background:#fff;}/*!sc*/ @media (max-width: 767px){.hUVZkP{display:none;}}/*!sc*/ data-styled.g24[id="HeaderNavSp__Wrapper-sc-14jg0n6-0"]{content:"hUVZkP,"}/*!sc*/ .hWYlUd{display:flex;justify-content:center;margin-top:40px;}/*!sc*/ data-styled.g25[id="HeaderNavSp__IconWrapper-sc-14jg0n6-1"]{content:"hWYlUd,"}/*!sc*/ .egqDVK{margin-top:50px;}/*!sc*/ data-styled.g26[id="HeaderNavSp__CorpWrapper-sc-14jg0n6-2"]{content:"egqDVK,"}/*!sc*/ .iFioks{display:flex;position:fixed;width:100vw;background:#fff;justify-content:center;z-index:100;transition:top 0.3s ease;top:-130px;padding:30px 30px 25px;box-shadow:none;}/*!sc*/ @media (max-width: 767px){.iFioks{display:none;}}/*!sc*/ data-styled.g27[id="StickyHeader__Wrapper-sc-1tro7id-0"]{content:"iFioks,"}/*!sc*/ .ipFjCB{display:flex;align-items:center;justify-content:space-between;width:100%;max-width:1400px;}/*!sc*/ data-styled.g28[id="StickyHeader__Inner-sc-1tro7id-1"]{content:"ipFjCB,"}/*!sc*/ .jZcOeb{display:flex;justify-content:center;padding:30px 30px 25px;background:#fff;}/*!sc*/ @media (max-width: 767px){.jZcOeb{position:fixed;z-index:100;width:100vw;padding:16px 20px 13px;box-shadow:0 1px 8px rgba(0,0,0,0.08);}}/*!sc*/ data-styled.g29[id="Header__Wrapper-sc-106uhe9-0"]{content:"jZcOeb,"}/*!sc*/ .dhzlK{display:flex;align-items:center;justify-content:space-between;width:100%;max-width:1400px;}/*!sc*/ data-styled.g30[id="Header__Inner-sc-106uhe9-1"]{content:"dhzlK,"}/*!sc*/ @media (max-width: 767px){.iVJYb{display:none;}}/*!sc*/ data-styled.g31[id="Header__HeaderNavPc-sc-106uhe9-2"]{content:"iVJYb,"}/*!sc*/ @media (max-width: 767px){.iZzKMA{display:none;}}/*!sc*/ data-styled.g32[id="FooterLogo__Pc-sc-1683ea-0"]{content:"iZzKMA,"}/*!sc*/ .cJGseb{display:none;}/*!sc*/ @media (max-width: 767px){.cJGseb{display:inline;}}/*!sc*/ data-styled.g33[id="FooterLogo__Sp-sc-1683ea-1"]{content:"cJGseb,"}/*!sc*/ .cwTvsA{font-size:13px;line-height:1.6;color:#f2f2f2;}/*!sc*/ @media (max-width: 767px){.cwTvsA{font-size:10px;}}/*!sc*/ data-styled.g34[id="FooterDescription__Text-sc-uki65r-0"]{content:"cwTvsA,"}/*!sc*/ .kdDnWo{display:flex;align-items:center;}/*!sc*/ @media (max-width: 767px){.kdDnWo{flex-direction:column;align-items:flex-start;}}/*!sc*/ data-styled.g35[id="FooterHeading__Wrapper-sc-ysx04u-0"]{content:"kdDnWo,"}/*!sc*/ .cGqMhn{margin-left:30px;}/*!sc*/ @media (max-width: 767px){.cGqMhn{margin:11px 0 0;}}/*!sc*/ data-styled.g36[id="FooterHeading__DescriptionWrapper-sc-ysx04u-1"]{content:"cGqMhn,"}/*!sc*/ @media (max-width: 767px){.dOceWS{display:flex;flex-wrap:wrap;justify-content:space-between;}}/*!sc*/ @media (max-width: 767px){.jBZdg{display:block;flex-wrap:wrap;justify-content:space-between;}}/*!sc*/ data-styled.g37[id="FooterNavLinks__LinkList-sc-he94nd-0"]{content:"dOceWS,jBZdg,"}/*!sc*/ .YkDvs{display:flex;flex-wrap:wrap;margin:16px 0 0 -10px;}/*!sc*/ @media (max-width: 767px){.YkDvs{justify-content:space-between;margin:0;}}/*!sc*/ data-styled.g38[id="FooterNavLinks__TagLinkList-sc-he94nd-1"]{content:"YkDvs,"}/*!sc*/ .ixQQMe{flex-basis:50%;margin-top:13px;}/*!sc*/ .ixQQMe:first-child{margin-top:29px;}/*!sc*/ @media (max-width: 767px){.ixQQMe{margin-top:17px;}.ixQQMe:first-child{margin-top:17px;}}/*!sc*/ data-styled.g39[id="FooterNavLinks__LinkItem-sc-he94nd-2"]{content:"ixQQMe,"}/*!sc*/ .lhjcLx{margin:13px 0 0 10px;}/*!sc*/ @media (max-width: 767px){.lhjcLx{flex-basis:50%;margin:17px 0 0 0;}}/*!sc*/ data-styled.g40[id="FooterNavLinks__TagLinkItem-sc-he94nd-3"]{content:"lhjcLx,"}/*!sc*/ .dkcwbg{margin-top:20px;}/*!sc*/ data-styled.g41[id="FooterNavLinks__MoreLinkWrapper-sc-he94nd-4"]{content:"dkcwbg,"}/*!sc*/ .hVwNys{display:flex;justify-content:space-between;margin-top:40px;}/*!sc*/ @media (max-width: 767px){.hVwNys{flex-direction:column;}}/*!sc*/ data-styled.g42[id="FooterNav__Wrapper-sc-pvduf3-0"]{content:"hVwNys,"}/*!sc*/ .bXAwgS{max-width:480px;}/*!sc*/ .bXAwgS:nth-child(1),.bXAwgS:nth-child(2),.bXAwgS:nth-child(4){flex-shrink:0;}/*!sc*/ .bXAwgS:not(:first-child){margin-left:20px;}/*!sc*/ @media (max-width: 767px){.bXAwgS{max-width:initial;}.bXAwgS:not(:first-child){margin:40px 0 0;}}/*!sc*/ data-styled.g43[id="FooterNav__LinksWrapper-sc-pvduf3-1"]{content:"bXAwgS,"}/*!sc*/ .gPDJrz{margin-top:30px;}/*!sc*/ @media (max-width: 767px){.gPDJrz{margin-top:20px;}}/*!sc*/ data-styled.g44[id="FooterNav__CorpLogoWrapper-sc-pvduf3-2"]{content:"gPDJrz,"}/*!sc*/ .icmzgP{background-color:#1b1b1b;}/*!sc*/ data-styled.g45[id="Footer__Wrapper-sc-1cjwj21-0"]{content:"icmzgP,"}/*!sc*/ .eQGFNj{width:100%;max-width:1400px;padding:45px 30px 18px;margin:0 auto;}/*!sc*/ @media (max-width: 767px){.eQGFNj{padding:40px 20px 20px;}}/*!sc*/ data-styled.g46[id="Footer__Inner-sc-1cjwj21-1"]{content:"eQGFNj,"}/*!sc*/ .eKVIfm{margin-top:84px;text-align:center;}/*!sc*/ @media (max-width: 767px){.eKVIfm{margin-top:39px;}}/*!sc*/ data-styled.g47[id="Footer__CopyrightWrapper-sc-1cjwj21-2"]{content:"eKVIfm,"}/*!sc*/ .WitCQ{position:relative;width:70px;height:70px;cursor:pointer;background-color:#1b1b1b;border:none;border-radius:50%;outline:none;appearance:none;}/*!sc*/ @media (max-width: 767px){.WitCQ{width:52px;height:52px;}}/*!sc*/ .WitCQ::before{position:absolute;top:45%;left:50%;display:block;width:12px;height:12px;content:"";border-top:2px solid #fff;border-left:2px solid #fff;transform:translate(-50%) rotate(45deg);}/*!sc*/ @media (max-width: 767px){.WitCQ::before{width:7px;height:7px;}}/*!sc*/ data-styled.g48[id="ToTopButton__Button-sc-60bzld-0"]{content:"WitCQ,"}/*!sc*/ .fDmxku{display:flex;justify-content:center;}/*!sc*/ data-styled.g49[id="TopButtonWrapper__Wrapper-sc-ssgdg7-0"]{content:"fDmxku,"}/*!sc*/ .daaPTY{display:flex;justify-content:flex-end;width:100%;max-width:1400px;padding:0 30px 30px;}/*!sc*/ @media (max-width: 767px){.daaPTY{padding:0 20px 20px;}}/*!sc*/ data-styled.g50[id="TopButtonWrapper__Inner-sc-ssgdg7-1"]{content:"daaPTY,"}/*!sc*/ html,body,div,span,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,abbr,address,cite,code,del,dfn,em,img,ins,kbd,q,samp,small,strong,sub,sup,var,b,i,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary,time,mark,audio,video{padding:0;margin:0;font-size:100%;vertical-align:baseline;background:transparent;border:0;outline:0;}/*!sc*/ body{line-height:1;}/*!sc*/ article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block;}/*!sc*/ blockquote,q{quotes:none;}/*!sc*/ blockquote::before,blockquote::after,q::before,q::after{content:'';content:none;}/*!sc*/ a{padding:0;margin:0;font-size:100%;vertical-align:baseline;background:transparent;}/*!sc*/ ins{color:#000;text-decoration:none;background-color:#ff9;}/*!sc*/ mark{font-style:italic;font-weight:bold;color:#000;background-color:#ff9;}/*!sc*/ del{text-decoration:line-through;}/*!sc*/ abbr[title],dfn[title]{cursor:help;border-bottom:1px dotted;}/*!sc*/ table{border-spacing:0;border-collapse:collapse;}/*!sc*/ hr{display:block;height:1px;padding:0;margin:1em 0;border:0;border-top:1px solid #ccc;}/*!sc*/ input,select{vertical-align:middle;}/*!sc*/ html{font-family:'Helvetica Neue',Arial,YuGothic,'Yu Gothic Medium','Yu Gothic','Hiragino Kaku Gothic ProN','Hiragino Sans',Meiryo,sans-serif;background:#f6f6f6;}/*!sc*/ *{box-sizing:border-box;line-height:1;}/*!sc*/ *:not(code,code *){color:#1b1b1b;}/*!sc*/ a:hover{color:#767676;opacity:0.8;}/*!sc*/ ul,ol{list-style:none;}/*!sc*/ data-styled.g51[id="sc-global-egvZzt1"]{content:"sc-global-egvZzt1,"}/*!sc*/ .eXXaLr{display:flex;justify-content:center;padding:50px 30px 60px;}/*!sc*/ @media (max-width: 767px){.eXXaLr{padding:74px 0 50px;}}/*!sc*/ data-styled.g52[id="Layout__Wrapper-sc-wljzn2-0"]{content:"eXXaLr,"}/*!sc*/ .cmfBeF{width:100%;max-width:1340px;}/*!sc*/ data-styled.g53[id="Layout__Inner-sc-wljzn2-1"]{content:"cmfBeF,"}/*!sc*/ .hWiQHX{font-size:20px;font-weight:bold;line-height:calc(20 / 14);}/*!sc*/ @media (max-width: 767px){.hWiQHX{font-size:18px;line-height:calc(18 / 14);}}/*!sc*/ data-styled.g54[id="SidebarHeading__Text-sc-100o8h8-0"]{content:"hWiQHX,"}/*!sc*/ .kOYsxR{display:block;}/*!sc*/ .kOYsxR img{width:100%;}/*!sc*/ data-styled.g55[id="SidebarImage__ExternalLink-sc-1ovfkzr-0"]{content:"kOYsxR,"}/*!sc*/ @media (max-width: 1399px){.ckiZSO{height:auto;width:100%;min-width:310;}}/*!sc*/ data-styled.g56[id="SidebarImage__Image-sc-1ovfkzr-1"]{content:"ckiZSO,"}/*!sc*/ .dlwWsb{margin-top:18px;}/*!sc*/ data-styled.g57[id="SidebarInformation__Item-sc-n9a31x-0"]{content:"dlwWsb,"}/*!sc*/ .bWRSUM{padding:20px;margin-top:19px;background-color:#fff;}/*!sc*/ data-styled.g58[id="SidebarLatestArticles__List-sc-4r6ql-0"]{content:"bWRSUM,"}/*!sc*/ .kxdipa:not(:first-of-type){padding-top:16px;margin-top:12px;border-top:1px solid #eee;}/*!sc*/ data-styled.g59[id="SidebarLatestArticles__Item-sc-4r6ql-1"]{content:"kxdipa,"}/*!sc*/ .fkdbFp{font-size:12px;color:#666;}/*!sc*/ data-styled.g60[id="SidebarLatestArticles__Date-sc-4r6ql-2"]{content:"fkdbFp,"}/*!sc*/ .cAFnYh{display:inline-block;margin-top:5px;font-size:16px;font-weight:bold;line-height:1.7;color:#1b1b1b;text-decoration:none;}/*!sc*/ data-styled.g61[id="SidebarLatestArticles__ArticleLink-sc-4r6ql-3"]{content:"cAFnYh,"}/*!sc*/ .ddvARG{display:inline-block;padding:8px 15px;font-size:14px;text-decoration:none;background:#fff;border:1px solid #ddd;border-radius:30px;}/*!sc*/ @media (max-width: 767px){.ddvARG{padding:8px 12px;font-size:13px;}}/*!sc*/ .ddvARG::before{content:"#";}/*!sc*/ .eZNwhP{display:inline-block;padding:8px 15px;font-size:14px;text-decoration:none;background:#fff;border:none;border-radius:30px;}/*!sc*/ @media (max-width: 767px){.eZNwhP{padding:8px 12px;font-size:13px;}}/*!sc*/ .eZNwhP::before{content:"#";}/*!sc*/ data-styled.g62[id="Tag__StyledLink-sc-1jf1fx3-0"]{content:"ddvARG,eZNwhP,"}/*!sc*/ .govONA{display:flex;flex-wrap:wrap;margin-top:9px;margin-left:-12px;}/*!sc*/ @media (max-width: 767px){.govONA{margin-top:7px;}}/*!sc*/ data-styled.g63[id="SidebarTags__List-sc-1sqne6a-0"]{content:"govONA,"}/*!sc*/ .cqMIrZ{margin-top:11px;margin-left:12px;}/*!sc*/ @media (max-width: 767px){.cqMIrZ{margin-top:12px;}}/*!sc*/ data-styled.g64[id="SidebarTags__Item-sc-1sqne6a-1"]{content:"cqMIrZ,"}/*!sc*/ .jsxPmt{margin-top:22px;}/*!sc*/ data-styled.g65[id="SidebarTags__NavLinkWrapper-sc-1sqne6a-2"]{content:"jsxPmt,"}/*!sc*/ .cfbUWz{width:310px;margin-left:30px;}/*!sc*/ @media (max-width: 1399px){.cfbUWz{width:calc(100 / 1400 * 310vw);margin-left:calc(100 / 1400 * 30vw);}}/*!sc*/ @media (max-width: 767px){.cfbUWz{width:100%;max-width:initial;margin:80px 0 0 0;}}/*!sc*/ data-styled.g66[id="Sidebar__Wrapper-sc-e0afmy-0"]{content:"cfbUWz,"}/*!sc*/ .liqkbQ:not(:first-of-type){margin-top:60px;}/*!sc*/ @media (max-width: 767px){.liqkbQ:not(:first-of-type){margin-top:46px;}}/*!sc*/ data-styled.g67[id="Sidebar__Inner-sc-e0afmy-1"]{content:"liqkbQ,"}/*!sc*/ .dYVJnu{position:sticky;top:0px;}/*!sc*/ data-styled.g68[id="Sidebar__StickyInner-sc-e0afmy-2"]{content:"dYVJnu,"}/*!sc*/ .OPsHt{display:flex;justify-content:space-between;margin-top:50px;}/*!sc*/ @media (max-width: 767px){.OPsHt{flex-direction:column;margin-top:0;}}/*!sc*/ data-styled.g69[id="page__FullWidthContent-sc-dlpr27-0"]{content:"OPsHt,"}/*!sc*/ .elZjqD{width:100%;}/*!sc*/ data-styled.g70[id="page__LeftColumn-sc-dlpr27-1"]{content:"elZjqD,"}/*!sc*/ .kdQgRZ{display:flex;justify-content:center;}/*!sc*/ data-styled.g71[id="page__Wrapper-sc-dlpr27-2"]{content:"kdQgRZ,"}/*!sc*/ .eza-DsE{display:flex;}/*!sc*/ @media (max-width: 767px){.eza-DsE{padding:0 20px;}}/*!sc*/ data-styled.g72[id="page__SidebarWrapper-sc-dlpr27-3"]{content:"eza-DsE,"}/*!sc*/ .irjTJi{font-size:14px;color:#666;}/*!sc*/ @media (max-width: 767px){.irjTJi{font-size:13px;}}/*!sc*/ data-styled.g74[id="ArticleDate__Text-sc-a95f93-0"]{content:"irjTJi,"}/*!sc*/ .fxciTM{font-size:30px;color:#1b1b1b;}/*!sc*/ @media (max-width: 767px){.fxciTM{font-size:22px;}}/*!sc*/ data-styled.g75[id="ArticleTitle__Text-sc-n1jdqj-0"]{content:"fxciTM,"}/*!sc*/ .ksKsDv{margin-top:16px;}/*!sc*/ @media (max-width: 767px){.ksKsDv{margin-top:12px;}}/*!sc*/ data-styled.g76[id="ArticleInfo__TitleWrapper-sc-1qj3yjx-0"]{content:"ksKsDv,"}/*!sc*/ .lpgjCc{display:flex;flex-wrap:wrap;margin-top:18px;}/*!sc*/ @media (max-width: 767px){.lpgjCc{margin-top:12px;}}/*!sc*/ data-styled.g77[id="ArticleInfo__TagList-sc-1qj3yjx-1"]{content:"lpgjCc,"}/*!sc*/ .idjGgX{margin-right:11px;margin-bottom:5px;}/*!sc*/ data-styled.g78[id="ArticleInfo__TagItem-sc-1qj3yjx-2"]{content:"idjGgX,"}/*!sc*/ .UTMQN{padding-bottom:18px;border-bottom:1px solid #eee;}/*!sc*/ @media (max-width: 767px){.UTMQN{padding-bottom:14px;}}/*!sc*/ data-styled.g79[id="OriginalInfo__Wrapper-sc-7610xd-0"]{content:"UTMQN,"}/*!sc*/ .dlhUOl{display:flex;align-items:center;padding:15px 20px;background-color:#f6f6f6;}/*!sc*/ @media (max-width: 767px){.dlhUOl{align-items:flex-start;padding:10px;}}/*!sc*/ data-styled.g80[id="OriginalInfo__Content-sc-7610xd-1"]{content:"dlhUOl,"}/*!sc*/ .jWRgds{font-size:14px;line-height:1.6;color:#666;}/*!sc*/ @media (max-width: 767px){.jWRgds{font-size:13px;}}/*!sc*/ data-styled.g82[id="OriginalInfo__TextArea-sc-7610xd-3"]{content:"jWRgds,"}/*!sc*/ .hulzJL{display:flex;}/*!sc*/ @media (max-width: 767px){.hulzJL{flex-direction:column;}}/*!sc*/ data-styled.g83[id="OriginalInfo__Information-sc-7610xd-4"]{content:"hulzJL,"}/*!sc*/ .cWvAEW{margin-top:12px;font-size:12px;}/*!sc*/ @media (max-width: 767px){.cWvAEW{margin-top:10px;font-size:10px;}}/*!sc*/ data-styled.g84[id="OriginalInfo__Note-sc-7610xd-5"]{content:"cWvAEW,"}/*!sc*/ .qHERx{margin-left:5px;}/*!sc*/ @media (max-width: 767px){.qHERx{margin-top:10px;margin-left:0;}}/*!sc*/ data-styled.g85[id="OriginalInfo__Author-sc-7610xd-6"]{content:"qHERx,"}/*!sc*/ .jPuUmd{color:#469af6;text-decoration:none;}/*!sc*/ data-styled.g86[id="OriginalInfo__ExternalLink-sc-7610xd-7"]{content:"jPuUmd,"}/*!sc*/ .kjRFXp{display:flex;justify-content:center;}/*!sc*/ data-styled.g89[id="ShareButtons__Wrapper-sc-1lies9q-0"]{content:"kjRFXp,"}/*!sc*/ .bzlnxh{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:center;}/*!sc*/ @media (max-width: 767px){.bzlnxh{justify-content:flex-start;}}/*!sc*/ data-styled.g90[id="ShareButtons__List-sc-1lies9q-1"]{content:"bzlnxh,"}/*!sc*/ .gaAEkH{padding-bottom:6px;}/*!sc*/ .gaAEkH:not(:first-child){margin-left:10px;}/*!sc*/ .gaAEkH:nth-child(3){padding-bottom:0;}/*!sc*/ @media (max-width: 767px){.gaAEkH:not(:first-child){margin-left:8px;}}/*!sc*/ data-styled.g91[id="ShareButtons__Item-sc-1lies9q-2"]{content:"gaAEkH,"}/*!sc*/ .bNqEXq img,.bNqEXq video{width:100%;}/*!sc*/ .bNqEXq div[style^='width']{max-width:100%!important;}/*!sc*/ .bNqEXq h2{padding-bottom:24px;margin-top:55px;font-size:26px;line-height:1.6;border-bottom:2px solid #707070;}/*!sc*/ @media (max-width: 767px){.bNqEXq h2{padding-bottom:16px;font-size:20px;}}/*!sc*/ .bNqEXq h3{margin-top:55px;font-size:24px;font-weight:bold;line-height:1.6;}/*!sc*/ @media (max-width: 767px){.bNqEXq h3{margin-top:44px;font-size:18px;}}/*!sc*/ .bNqEXq h3::before{padding-right:15px;content:'';border-left:5px solid #adb5bb;}/*!sc*/ @media (max-width: 767px){.bNqEXq h3::before{padding-right:11px;}}/*!sc*/ .bNqEXq h4{margin-top:50px;font-size:20px;font-weight:bold;line-height:1.6;}/*!sc*/ @media (max-width: 767px){.bNqEXq h4{margin-top:38px;font-size:16px;}}/*!sc*/ .bNqEXq p{margin-top:25px;font-size:17px;line-height:2;}/*!sc*/ @media (max-width: 767px){.bNqEXq p{margin-top:24px;font-size:15px;line-height:1.9;}}/*!sc*/ .bNqEXq a{color:#469af6;text-decoration:none;}/*!sc*/ .bNqEXq ul{margin-top:20px;}/*!sc*/ .bNqEXq ul li{position:relative;padding-left:1.8rem;font-size:17px;line-height:2;}/*!sc*/ .bNqEXq ul li:not(:first-of-type){margin-top:5px;}/*!sc*/ .bNqEXq ul li::before{position:absolute;top:13px;left:5px;display:inline-block;width:6px;height:6px;content:'';background-color:#1b1b1b;}/*!sc*/ @media (max-width: 767px){.bNqEXq ul li{padding-left:1.5rem;font-size:15px;}}/*!sc*/ .bNqEXq ol{margin-top:20px;counter-reset:item;}/*!sc*/ .bNqEXq ol li{padding-left:1.7rem;font-size:17px;line-height:2;text-indent:-1.7rem;}/*!sc*/ .bNqEXq ol li:not(:first-of-type){margin-top:5px;}/*!sc*/ @media (max-width: 767px){.bNqEXq ol li:not(:first-of-type){margin-top:8px;}}/*!sc*/ .bNqEXq ol li::before{padding-right:0.7rem;content:counter(item) '.';counter-increment:item;}/*!sc*/ @media (max-width: 767px){.bNqEXq ol li::before{padding-right:0.6rem;}}/*!sc*/ @media (max-width: 767px){.bNqEXq ol li{padding-left:1.4rem;font-size:15px;line-height:1.9;text-indent:-1.4rem;}}/*!sc*/ .bNqEXq em{font-style:italic;}/*!sc*/ .bNqEXq code{font-size:15px;line-height:1;}/*!sc*/ .bNqEXq pre .line-numbers-rows{padding:1em;font-size:15px;line-height:1;}/*!sc*/ .bNqEXq pre .line-numbers-rows span{padding:0.3em 0;}/*!sc*/ .bNqEXq blockquote{position:relative;padding:0 42px;}/*!sc*/ @media (max-width: 767px){.bNqEXq blockquote{padding:0 25px;}}/*!sc*/ .bNqEXq blockquote::before,.bNqEXq blockquote::after{position:absolute;width:24px;height:24px;content:'';background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAhlJREFUSA3tVEFuE1EMtT/TVZHoDeAIOUKy6Eg0RSS0rJmegHACwgnaniDTNalCBQEpQcrkBJQbNCegSKgbJmPsmfj3Z/J/tmz6N7af39ge2/8DPJz/3QEMFXA5niRAeApI747acRriCX45nvaB4K1BanXb8bXLNa6hehkccAAIe8By9G32TH11OfwySRl7L9yCcFb3R3Vg+PV7B4gGihPAVfd560ZtV5aVA7xRjJAuVFe51iKptFjmP6rKgfPQxfFhnCjZlR8/T5vGgFMxnfhaudai5fJvX4Nz+HkouCTi4KkmJKBzX/CSpySpHhHt7xqzk6ivLqsZwdMVvjhux706R237B0WRJwpKa0J9Fw4BdpTLVv9e39RsAiY2rduYT1b3K5bLf5r5KRVqhzwcT2/ZeCIw97SHgLyivKRI2auDeC66nNFstlfc5b8qi/0AHQJoiG2Arur3wCbglWOe/xBB9mg36nZbrdvN7al/QykP/ERRp0UKbUpEaC7v8sGmx4dgsrofpdNNsPDRFZNWiB49jq4VC0lu8Uv12QS8OZmCITkaTxrSJr6BP0McwXl+5UxEdxJgKkDo8IB+3w9wO5fXZK5xbILXL/Yz2X911CUS9BU7Otw/2/YXHLSnXJtAgNXT8EGqVUKl8zsjQZ1jdnea8kQ4kKiLooC1J5tn5z+yjlEU3Wy70fKl3Iv8T96Q4Zfz8Yd7QMMd+AeJjsQzpDMHYwAAAABJRU5ErkJggg==);}/*!sc*/ @media (max-width: 767px){.bNqEXq blockquote::before,.bNqEXq blockquote::after{width:20px;height:20px;background-size:20px 20px;}}/*!sc*/ .bNqEXq blockquote::before{top:4px;left:0;}/*!sc*/ @media (max-width: 767px){.bNqEXq blockquote::before{top:2px;}}/*!sc*/ .bNqEXq blockquote::after{right:0;bottom:4px;transform:rotate(180deg);}/*!sc*/ @media (max-width: 767px){.bNqEXq blockquote::after{bottom:4px;}}/*!sc*/ .bNqEXq table{width:100%;margin-top:25px;}/*!sc*/ .bNqEXq th{font-weight:bold;text-align:left;}/*!sc*/ .bNqEXq td,.bNqEXq th{padding:10px;font-size:15px;line-height:2;border:1px solid #e6e6e6;}/*!sc*/ @media (max-width: 767px){.bNqEXq td,.bNqEXq th{font-size:14px;}}/*!sc*/ .bNqEXq .admonition-info{background-color:#f6f6f6;border-left:8px solid #1b1b1b;}/*!sc*/ .bNqEXq .admonition-none{background-color:#f6f6f6;border-left:8px solid #1b1b1b;}/*!sc*/ .bNqEXq .admonition-none div:first-child{display:none;}/*!sc*/ .bNqEXq .admonition-info h5{color:#1b1b1b;}/*!sc*/ .bNqEXq .admonition-info .admonition-icon svg{stroke:#1b1b1b;fill:#1b1b1b;}/*!sc*/ .bNqEXq summary{cursor:pointer;}/*!sc*/ data-styled.g92[id="textPageStyles__TextPage-sc-1qtxiy0-0"]{content:"bNqEXq,"}/*!sc*/ .flbPUF{background-color:#f6f6f6;border-bottom:1px solid #eee;padding:25px 5%;align-items:normal;grid-template-columns:0.2fr 0.8fr;gap:0px 25px;grid-template-areas:". header" "img name" "img introduce";margin-top:50px;display:grid;grid-template-rows:0.1fr 0.2fr;}/*!sc*/ @media (max-width: 767px){.flbPUF{padding:30px 20px;align-items:center;gap:20px 20px;grid-template-areas:"header header" "img name" "introduce introduce";}}/*!sc*/ data-styled.g93[id="SupervisorInfo__Wrapper-sc-1j48flx-0"]{content:"flbPUF,"}/*!sc*/ .dvXvVG{grid-area:header;font-weight:normal;font-size:16px;}/*!sc*/ @media (max-width: 767px){.dvXvVG{font-weight:bold;font-size:20px;}}/*!sc*/ data-styled.g94[id="SupervisorInfo__Header-sc-1j48flx-1"]{content:"dvXvVG,"}/*!sc*/ .ftZoJh{grid-area:img;}/*!sc*/ data-styled.g95[id="SupervisorInfo__ImageWrapper-sc-1j48flx-2"]{content:"ftZoJh,"}/*!sc*/ .mBQUt{width:100%;height:auto;border-radius:50%;}/*!sc*/ data-styled.g96[id="SupervisorInfo__Image-sc-1j48flx-3"]{content:"mBQUt,"}/*!sc*/ .eoJhWn{grid-area:name;font-size:16px;font-weight:700;line-height:1.2;white-space:pre-wrap;}/*!sc*/ data-styled.g97[id="SupervisorInfo__NameWrapper-sc-1j48flx-4"]{content:"eoJhWn,"}/*!sc*/ .hPxcFm{line-height:2;}/*!sc*/ data-styled.g98[id="SupervisorInfo__Name-sc-1j48flx-5"]{content:"hPxcFm,"}/*!sc*/ .hHtnWv{grid-area:introduce;font-size:14px;line-height:1.5;white-space:pre-wrap;margin-top:15px;}/*!sc*/ @media (max-width: 767px){.hHtnWv{margin-top:0;}}/*!sc*/ data-styled.g99[id="SupervisorInfo__Introduce-sc-1j48flx-6"]{content:"hHtnWv,"}/*!sc*/ .dGIkDp{margin-top:8px;}/*!sc*/ data-styled.g100[id="SupervisorInfo__SocialLinkWrapper-sc-1j48flx-7"]{content:"dGIkDp,"}/*!sc*/ .lfoiSu{line-height:1.5;}/*!sc*/ data-styled.g101[id="SupervisorInfo__SocialLinkItem-sc-1j48flx-8"]{content:"lfoiSu,"}/*!sc*/ .gZbwdw{color:#469af6;}/*!sc*/ data-styled.g102[id="SupervisorInfo__SocialLink-sc-1j48flx-9"]{content:"gZbwdw,"}/*!sc*/ .fpWdTs{width:100%;object-fit:cover;font-family:"object-fit: cover";}/*!sc*/ @media (max-width: 767px){.fpWdTs{display:block;max-width:295px;min-height:192px;margin:0 auto;}}/*!sc*/ data-styled.g103[id="ArticleCardThumbnail__Thumbnail-sc-7xjim1-0"]{content:"fpWdTs,"}/*!sc*/ .aBiaF{display:block;font-size:16px;font-weight:bold;line-height:1.6;text-decoration:none;}/*!sc*/ data-styled.g104[id="ArticleCardTitle__Text-sc-1rk0g9j-0"]{content:"aBiaF,"}/*!sc*/ .etKuix{font-size:12px;color:#666;}/*!sc*/ data-styled.g106[id="ArticleCardDate__Text-sc-1wiuzo7-0"]{content:"etKuix,"}/*!sc*/ .flEpUP{padding-top:15px;}/*!sc*/ data-styled.g107[id="ArticleCardInfo__Wrapper-sc-c5jz68-0"]{content:"flEpUP,"}/*!sc*/ .mmaeQ{margin-top:10px;}/*!sc*/ data-styled.g108[id="ArticleCardInfo__TitleWrapper-sc-c5jz68-1"]{content:"mmaeQ,"}/*!sc*/ .biuIkY{margin-top:15px;}/*!sc*/ data-styled.g109[id="ArticleCardInfo__DescriptionWrapper-sc-c5jz68-2"]{content:"biuIkY,"}/*!sc*/ .jFjNGd{font-size:12px;color:#666;}/*!sc*/ .jFjNGd::before{content:"#";}/*!sc*/ data-styled.g110[id="ArticleCardTag__Text-sc-1bp09p2-0"]{content:"jFjNGd,"}/*!sc*/ .bHlduO{display:flex;flex-wrap:wrap;align-items:center;}/*!sc*/ .bHlduO::before{position:relative;top:2px;left:0;display:block;width:14px;height:14px;content:"";background:center/contain no-repeat url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEQAAABECAYAAAA4E5OyAAAAAXNSR0IArs4c6QAABCVJREFUeAHtm81rE0EUwN9sYxpEFJQeevEg4sWDVy8eIk0FsyK0xVO9SCu29KZ4EPUqQi8iflARUdtbIlTbUJpC/wLx5MmTICgUFUV60GzGN1sKm9nJZjY7MztLN4dk35s3M+/9svPmTT4A8kdOICeQE+ifAOm/q56e9dX1ywDkNo5+Qs8MO6NSSj86xLkxVh1ZC87jBIW0r2uN5hzCeIV+aIXB4iSEnKRAH/AxWwOktrp+jVB4yDuoU8a75Dg/vhVAfBhAnvDOpSGnDsQmGOwNSBWIbTBSBWIjjNSA2AojFSA2wzAOxHYYRoFkAYYxIKwCJUnrDArfsb68BZRUvAHviAeFYRxzFEvOu1hx/mbBxH1gtRraZQtxB4lr78NIWIFSgHoJStNu9cxPbv5vKDeXlzcWWgP0JRA4x7XHFrUe7hQtkxfj1coVmchqq813GJArY8tssHRvT7ijA0H70C0TbExyrQYG/XJ4f+GqrB/tIkxSCn9k7UV2WoAoyRnoLS6V+XK53BI5LtJdqlR+4bJ5JmoT6UQ5RDmQ+srGrKpTa7tA34oCidLRNsTuExxPKRC2TIDQR8EJklwPFYtf4/an4HyS7cNyCG+rDIianNHp3larNdip6S0Viq1/va26WygB4i+TpHWGwMfiXzgqUEeqqOccizQINGrJIQyGymUS8Bc8Si8EZZlr3GUuyth1s0l0h6jOGSEnCcxtbm6WQvouikajcRCbZro0h9RKc4iOnBHyGMjwj+3W87A+rMHgyDbdt4SF2aFwq7ymr0pV5zIRuY71yJsSLU25bqh0983ra2vD4DmLeNY5K+ofpcMquINBhxDVcbetttKcIQQe78qmXvEAt4XzzrcJvKek/QHr7UHiFU6h/jTmjevYdqAfX3ggsQ53O8vEPAwWKJ5sh7B0ve/g7QKwc/xAGEzAA6//EvspUQ7RtbXGjkJth8/8cFK7jOmcwTupS3Yc5w4/dk8g2rdW3iNDMi63mbHzI0v8dJGrz8zWyrukX2YwJqqjT0UzdQWyF2EwQEIgexWGEEhtZX0SDz2vRbdTlnVYq8xOuJWeX6iHkiru6feyHLjId1kYrG8ICOo6PnQVTZAlXRwYLK4QEBzgZpYCjvI1LgwhEPxYfpFtS1ETZaHN31olcgYfi3CXYUZZ3mmi6gweAC93BZJVKElgsJgjgWQNSlIYUkCyAkUFDGkgtkNRBSMWEFuhqIQRG4htUFTD6AuILVB0wOgbSNpQdMFIBCQtKDphJAZiGopuGEqAmIJiAoYyILqhmIKhFIguKCZhKAeiGoppGFqAqIKSBgxtQJJCSQuGViD9QkkThnYgcaGkDcMIEFkoNsAwBqQXFFtgGAXSDYpNMIwD8aE0mtP40+8Fdo3/fZkad0ekflTn2+dPOYGcQE7AcgL/ASA0wmeGWLjlAAAAAElFTkSuQmCC);}/*!sc*/ data-styled.g111[id="ArticleCardTagsList__List-sc-1wyunq3-0"]{content:"bHlduO,"}/*!sc*/ .eGBDcv{margin-left:9px;white-space:nowrap;}/*!sc*/ data-styled.g112[id="ArticleCardTagsList__Item-sc-1wyunq3-1"]{content:"eGBDcv,"}/*!sc*/ .jhDMNW{background-color:#f6f6f6;border-bottom:1px solid #eee;width:100%;margin-top:20px;padding:20px;}/*!sc*/ data-styled.g113[id="RelatedPostsList__Wrapper-sc-4059vb-0"]{content:"jhDMNW,"}/*!sc*/ .ccjKdX{padding:0 0 10px 10px;grid-area:header;font-weight:normal;font-size:16px;}/*!sc*/ @media (max-width: 767px){.ccjKdX{font-weight:bold;font-size:20px;}}/*!sc*/ data-styled.g114[id="RelatedPostsList__Header-sc-4059vb-1"]{content:"ccjKdX,"}/*!sc*/ .XNfFC{display:grid;gap:20px;grid-template-columns:repeat(3,minmax(30%,1fr));}/*!sc*/ @media (max-width: 1399px){.XNfFC{grid-template-columns:repeat(2,minmax(40%,1fr));}}/*!sc*/ @media (max-width: 767px){.XNfFC{grid-template-columns:1fr;}}/*!sc*/ data-styled.g115[id="RelatedPostsList__GridWrapper-sc-4059vb-2"]{content:"XNfFC,"}/*!sc*/ .iVnrAu{display:grid;grid-template-columns:repeat(1,minmax(30%,1fr));grid-template-rows:auto auto 1fr auto;grid-template-areas:"thumbnail" "info" "." "tags";padding:20px;background:#fff;box-shadow:0 0 5px rgba(0,0,0,0.05);align-items:start;min-width:0;max-width:100%;}/*!sc*/ @media (max-width: 767px){.iVnrAu{grid-template-columns:minmax(30%,150px) 1fr;grid-template-rows:auto auto;grid-template-areas:"thumbnail info" "thumbnail tags";gap:10px 20px;}}/*!sc*/ data-styled.g116[id="RelatedPostsList__Card-sc-4059vb-3"]{content:"iVnrAu,"}/*!sc*/ .dsGZua{grid-area:thumbnail;}/*!sc*/ data-styled.g117[id="RelatedPostsList__ThumbnailWrapper-sc-4059vb-4"]{content:"dsGZua,"}/*!sc*/ .lnIryr{grid-area:info;}/*!sc*/ data-styled.g118[id="RelatedPostsList__InfoWrapper-sc-4059vb-5"]{content:"lnIryr,"}/*!sc*/ .dzSQvE{grid-area:tags;}/*!sc*/ data-styled.g119[id="RelatedPostsList__TagsWrapper-sc-4059vb-6"]{content:"dzSQvE,"}/*!sc*/ .lbIhIM{max-width:875px;padding:50px 80px 60px;background-color:#fff;}/*!sc*/ @media (max-width:1236px){.lbIhIM{max-width:calc(100 / 1400 * 951vw);}}/*!sc*/ @media (max-width: 767px){.lbIhIM{max-width:100%;padding:50px 20px 50px;}}/*!sc*/ data-styled.g120[id="article__Inner-sc-19k0vly-0"]{content:"lbIhIM,"}/*!sc*/ .ikOPxI{width:100%;height:auto;max-height:350px;margin-top:20px;object-fit:contain;}/*!sc*/ data-styled.g121[id="article__MainVisual-sc-19k0vly-1"]{content:"ikOPxI,"}/*!sc*/ .hRbWsE{margin-top:18px;}/*!sc*/ @media (max-width: 767px){.hRbWsE{margin-top:14px;}}/*!sc*/ data-styled.g122[id="article__OriginalWrapper-sc-19k0vly-2"]{content:"hRbWsE,"}/*!sc*/ .ezXiKj{margin-top:60px;}/*!sc*/ @media (max-width: 767px){.ezXiKj{margin-top:50px;}}/*!sc*/ data-styled.g123[id="article__ShareButtonsWrapper-sc-19k0vly-3"]{content:"ezXiKj,"}/*!sc*/ </style><link rel="preconnect" href="https://www.googletagmanager.com"/><link rel="dns-prefetch" href="https://www.googletagmanager.com"/><link rel="alternate" type="application/rss+xml" title="POSTD" href="/feed/"/><title data-gatsby-head="true">アルゴリズムのパフォーマンスを段階的に改善する | POSTD</title><link rel="icon" type="image/ico" href="/static/favicon-730c2b8b363f1d98a40b76cde8ccdc73.ico" data-gatsby-head="true"/><link rel="apple-touch-icon-precomposed" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJAAAACQCAIAAABoJHXvAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3NpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDplMTE0N2M1NS1hYmIzLTQwN2YtOGRmMy0zNzRhM2JkNGRkYmYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NjIwMEM5N0ZGMkM4MTFFMzgxMjM5NDExNDlEMUM0REMiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NjIwMEM5N0VGMkM4MTFFMzgxMjM5NDExNDlEMUM0REMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6YTBhOWE0NTEtYTc4OC00Y2ZjLTgyYWYtNGFjMDIzY2UwNzU0IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOmUxMTQ3YzU1LWFiYjMtNDA3Zi04ZGYzLTM3NGEzYmQ0ZGRiZiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpKUn6UAAAR3SURBVHja7Ny/Szp9AMDxJzPS1AyDDCQxK+nn0KAVYVANBWKWSEtTEf0JNQVNbUFjS1NDWEMR1VQ29IPmcigKJbChyCIDKYR8Dr4Pz/B9HrzTvnpnvd9DUHzqrnt13ue8u0rS6fRfVDyVAAYYAUaAAUaAEWCAEWAEGGAEGAEGGAFGgAFGgBFggBFgBBhgBBgBBhgBRoABBhhgBBgVCKykpOS3r/x3iVLGiH5Lbmk0Gq1WazKZLBaL3W5vamrq7Ozs6empqqoCTIlg/5tKpXK5XKOjo36/XyBUllg6z0lZYg5rVbDt09/fv7m5mUql0soIMEk5HI5gMPj5+QlYcYD9qru7OxwOA1Y0YELl5eWLi4sy7mqA5ZLP50skErKAMUvMsY6OjoODg5qaGqb1xQEm1NraGgqFzGYzYF8Fq6io8Hg8UlZPmK8/Pz9Ho9FYLJbDphD2s+PjY6PRyHnYl45hVqs12/WMx+M7OzvT09MmkymrDej1egs5BwHs95LJ5MrKivATpJstLS0BJhvYv2xzc3NqtVriG5LX19eAyQn2q6Ojo+rqailmQ0NDgMkPJnR1dVVbWyvF7PDwEDD5wYQuLi70er0o2MDAAGCKABMKBoNSTmBubm7yvT1VXMOV0vj4eCAQED1BWl1d5TxMEXuYkDAPFJ002u129jCl5HA4/H5/5jGRSESYpOR1NQDLosnJSdExJycngCmlwcFBnU6Xeczl5SVgSqmsrKy3tzfzGOFQB5iCam9vzzzg9vYWMAVls9kyD3h6egJMQYle+np9fQVMQYmeiqlUKsAU1NvbW+YBBoMBMAX1+Pj4xddMwAqa6Kw93/fkAJZdZ2dnmQe0tLQAppSEc6xoNApY0bS2tiY6pqurK6/r8D3vS7RarXd3d3/2F0kmk3a7/eHhIcMYrVYbj8eFj+xh8re8vJxZS8jj8eRV65+/ZS5gSrkVR6PRiG7M3d1dLmDKXyKRCAQC7+/vmYfV1dUNDw/ne2UAEz90eb3ecDgsOnJ2dra0tDTvK8RLYoZisZjT6ZSyGevr6z8+PrjNTU6w9fV16Y9/bW1tceevbGChUMjtdkt/lZqYmOBhiEKDCXOK09PT+fn55ubmrI4pjY2NwrkXj8wW6IE+IWFz39/fRyKRVCqV7W9nNBrPz8+zNeadDnnS6/V7e3t9fX2FXChgOVZZWbm/vy96ExVgigATjlvb29ttbW0yLPtbTjry2tjY2MvLS1qmAMsis9m8sbGRljXApB6xFhYW5PrvN99/Wv9nD1czMzNTU1MSH3Zm0iEPWENDg8/nGxkZcbvd+b7VELAsUqvVBoNBp9NZLBabzWa3251Op8vlEj5V5tWDYgX7sQEGGGCAEWCAAQYYAQYYYIAB9h3AlHBPgJTyvj0BAwwwwAADDDDAfgwYAQYYYIARYIABBljxTtmZ1gMGGGCAAQYYYIDRD53WE2CAEWAEGAEGGAFGgAFGgBFggBFgBBhgBBgBBhgBRoABRoARYIARYAQYYAQYAQYYFUt/CzAAPkGUpXqQ7qgAAAAASUVORK5CYII=" data-gatsby-head="true"/><script type="text/javascript" id="mierucajs" data-gatsby-head="true"> window.__fid = window.__fid || [];__fid.push([298475738]); (function() { function mieruca(){if(typeof window.__fjsld != "undefined") return; window.__fjsld = 1; var fjs = document.createElement('script'); fjs.type = 'text/javascript'; fjs.async = true; fjs.id = "fjssync"; var timestamp = new Date;fjs.src = ('https:' == document.location.protocol ? 'https' : 'http') + '://hm.mieru-ca.com/service/js/mieruca-hm.js?v='+ timestamp.getTime(); var x = document.getElementsByTagName('script')[0]; x.parentNode.insertBefore(fjs, x); }; setTimeout(mieruca, 500); document.readyState != "complete" ? (window.attachEvent ? window.attachEvent("onload", mieruca) : window.addEventListener("load", mieruca, false)) : mieruca(); })(); </script><script src="https://b.st-hatena.com/js/bookmark_button.js" data-gatsby-head="true"></script><script src="https://platform.twitter.com/widgets.js" data-gatsby-head="true"></script><script crossorigin="anonymous" src="https://connect.facebook.net/ja_JP/sdk.js#xfbml=1&version=v10.0" nonce="jX8miYcO" data-gatsby-head="true"></script><script src="https://widgets.getpocket.com/v1/j/btn.js?v=1" id="pocket-btn-js" data-gatsby-head="true"></script></head><body><div id="___gatsby"><div style="outline:none" tabindex="-1" id="gatsby-focus-wrapper"><header class="Header__Wrapper-sc-106uhe9-0 jZcOeb"><div class="Header__Inner-sc-106uhe9-1 dhzlK"><div class="HeaderLeftSide__Wrapper-sc-151me4h-0 icgTxN"><a href="/"><h1 class="HeaderLogo__Pc-sc-128t2eb-0 hLsmrx"><img src="/static/logo-10ab68d2ba3b6095a7c9c0d4ce901428.png" alt="POSTD PRODUCED BY NIJIBOX" width="160" height="75"/></h1><h1 class="HeaderLogo__Sp-sc-128t2eb-1 djySHL"><img src="/static/logo-10ab68d2ba3b6095a7c9c0d4ce901428.png" alt="POSTD PRODUCED BY NIJIBOX" width="96" height="45"/></h1></a><div class="HeaderLeftSide__DescriptionWrapper-sc-151me4h-1 iteQnd"><p class="HeaderDescription__Text-sc-clsdq0-0 fcSJox">ニジボックスが運営する<br/>エンジニアに向けた<br/>キュレーションメディア</p></div></div><nav class="Header__HeaderNavPc-sc-106uhe9-2 iVJYb"><div class="HeaderIcons__Wrapper-sc-fl6baq-0 hyUZWO"><a href="https://feedly.com/i/subscription/feed%2Fhttps%3A%2F%2Fpostd.cc%2Ffeed%2F" target="_blank" rel="noopener noreferrer" class="HeaderIconLink__ExternalLink-sc-nsmdxc-0 egfLUA"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAA5BJREFUaAXtWLFSGzEQ5bh4JmODB6g8doHp0iV/QNylCyUddpmOdOkSunSZfAFHBx18QfwHoU1HCuw2HsYeGtt57+bEyHfSnfbuTMyEnfFIWmlX70larc5ra8/yvAL/9wp4y6DfarWO5vP5sed5byL/fZTB7e3tWdnzlU6g2WyeAnjXBBSkgsFg0DP15dX5eQ1NdmngOZ47srm52b67u7sy2efRlUYgC7wCVzaJUgi4gl8GiUIxsAWpVqs/tGBVGJ3KMmIi9w4UBU+GZRynXDtQBnh9i7AT15PJpPMHoutd6mICZYNXIPOSEBGQggeoEwLEUfmsgKaVeUi8SHOo90nBw7aHpBXQBzLzDYpT1tOEMcFLAWOcj5NTEOcBj2dDoMAicV3X6/XfaB8ona0EiUalUnnn+/7FPcQ2TukzCRQFryYiCWThPa6y0tlKCYnUGCgLPIHiGBE4j8cW2y7iEhNWAv8avCKYRcJIYFXAu5BIEFg18FkkFgisKvg0Eg8EVh28jURI4KmAN5FYXyZ43CBX/KmJyyqZS6KMvebv7Ox8guLQ0XlPz7C6TfyeB/AzPCUOkcDOXROY7i+rzmS3sbEx8uH8GxtZBuiXgu8qnyBxuQwS8N/wsHJzNVFK+R0rf2zqt6x81zQWn56XWKz3pr68unUXQxyHfcZKfKwEfKPRaMP+ddxHwfZo3SXIsGph0OgkJOA5Fq/Ln/DTLgh4wRzY+x5W5i2c85GVKTC4waAAvzbAHKAMdwV6BmwX7YTEiSYGFFBMp9NOmAcwSRd+TvP4AvgTgP9isl0meMwXXirh94Dkg0MHOpvNPg6Hw6+6TtUfAzznenhKsCHdifF4vG36J+GxwBPzwi0UJakeO1yE2VAPbNo8JnjOl/iklBwnBPLC92scPOKDz4hfGPeKkxUUYyJdOEL6BNLjpNuyrt9MSGABSBzFxwjaRvC0T+yAcirZCWWjSh08dQWfElbw9G3dAXZSpDvBY4NrlTkiIfDVh3I/0WFXpIKn2UIQm/xIAxs+duOBTb/UgdyuaQ6LLhM87TIJcJCEBM564tlB8NHf8G36cxAn8PSTeYT0ySTHCat9DdvLyP6AxHRfKXVn8PQhIkADCQmOF4oIPH1bbyHbxEVuJ5vPSC8GTzsxARppJDpovqSugIxg+yGKM7GbXAQ4C0nUarVznO1t/PagkhIZIU4u8CA8xIOwT5/P8hRX4C/0uyMrvpz0RwAAAABJRU5ErkJggg==" alt="Feedly" width="24" height="24"/></a><a href="https://postd.cc/feed/" target="_blank" rel="noopener noreferrer" class="HeaderIconLink__ExternalLink-sc-nsmdxc-0 egfLUA"><img src="data:image/png;base64,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" alt="RSS" width="24" height="24"/></a><a href="https://twitter.com/POSTDcc" target="_blank" rel="noopener noreferrer" class="HeaderIconLink__ExternalLink-sc-nsmdxc-0 egfLUA"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAVmSURBVHgBzVm7UhtJFL2SoEpbvOSCQLyqRObMkHkzKcMZZOsIyHYj5C9AZHZkKVtHEpkdGaJ1hsg2Ywg38pj3ZjIQYJ4+Z9wzNRo9puch4FRJ6mn19Nzue+7p2z0JiQG5XC5zfX29gOKL+/v7HH5nk8lkBuWM3QZlM5FImCga+Oz19/fXTUAiIiEhQaOvrq5WYVQel3kJBw6mEmUwgQdgG44ZLrpnOAbUMJD1oAMJNICJiYm1HhjeBPRdOj4+XtdtrzUAzHoOHP+M4qw8DEx4o6DjjaRfg8nJyaWbm5tdeTjjCU7YLjy+4Ncw1e1PUgZBWkYxLQ+PNJ79x9DQkJyfn+90atRxAMr4kjwyqHLdBtF2AHQdbvxbngg4iOHhYROD2Gv5z1vBgCXne6k0IdFAYM95A7sliBE820/QeCKjlLAJTRRSvPeN/EdEdmRkJHF2dla3KxwKKa3/6tcDvLOIhWaz3X9TU1Ml/L8mwbBxdHS0DLmmTO9qtCeVZsCkBi8cDwwMDLwXDa2Hh+ZHR0c/NQA8dBnBNcsP6hr7+/ubKNODWdGDAeNfcfLu7u7+wbUOddOYpB+2F6wYYAf4WRY9kItVu4wPy1W77vb2dhGDbGj0Y7Kt8vw2zRBNYACrzMlYtjyA2eesBeF+bnBw8DuoVMaM59XDrbrT09Mv0O0fuJ6X7sYX0NbEs2n8cwkGxwtWDIAKYVIFS9YuLy+lr6/PLbtzoIWBPmlYvsO9dhvStijhUEcfhYRu8HbrBIbQiPeqzlQDy3gGZuMN7inHsdLjOc9SIejjhkMlyBs9SCpkEJDpk5OTT14qweB1GP8WarWKy7cSHf8l0FmZQSHRMIfZMJlBigpGGFs4PDysu6hUgfHFAHKpg0oSxr+Q6KhSl2H0il2BfqtUCgQr60i1olK7zxITuP9Owc0lPDhq6pCFGmVg5AdQ6RmuX+JD45+DSh+QhG2EkUs/wO50El85iQdF0DGPwC2hbKoHLIyPj1sqo04tchIvMglw8l7ig6VAyGZn4d5tVWfJLX/dMRIXfLeUAUGarDF4qTiqzlq5vTESF1LgLF0c55bxJeJhC/Hw0btKQ24/umIkFiSh2Tp5SxBQLnlgxbxoxc6LcByzRgl1x0gMMNFv0pD4YNhyyTSBuQ5iwaGS/Er8JC4q8agyBTf/LvG4lAnaq7GxsYySy3lI9B5oU3NRKctV2iO3UbBFFVoWNTMRYGWX6XTaqzSOAkGZvtp5kWuVjnretJLEAzYlAhTHF0kXGFmVZpl0FIht7ErXKq27d2gL3F9PYWN16XJxYCCG/sJsfmF2ics/2zRpp0BM+LJYpTc09g6dYOD+d9Y6gFnYCdGBlV0eHBzU/FJjKhAD26NA3AcvMbVGuS7BUbFs4Bfd6eaobgdUHHUIppOgWXsHphveVbrNpsgXoM8MaWttKRWNfhPNFxUwmMa85qziodyM6yyEbiol1LPSoNIsqFAJSKUa6WfZ4vSu7wVTKUsmRHbJgC3YC50XPttQB/bss9x0tKh5rlODB76h3ZKEC3wD92+1+0O9X1vqdjPjDqJRcq69DWLQ5l7ChPdm3BUt2WhUbe4VaBMXS299y/H6xcVFAwH1v4Tf6PcEoNdrBO6/3vq27wewBTRcSvHoUKcZbd9XdHxDw1OvpzAIb9C2/C8+mJ6eXmDu8tDvDMh5fN5wpe/aTjSQzWZzqVQq1hMFHxgUE1vruyElGmBgIy4qvaaUmvV3XOX5TK17JCCUN0ris+AEgZLtCvKhsv3iQvteCQk1kDwevor4CLXwMafCz04Yw50+JAbYg5FfKziPKnPiihfOMAZJehj4/YYqgxupsEa78RMK9vsn6EQJOAAAAABJRU5ErkJggg==" alt="Twitter" width="24" height="24"/></a><a href="https://www.facebook.com/postdcc" target="_blank" rel="noopener noreferrer" class="HeaderIconLink__ExternalLink-sc-nsmdxc-0 egfLUA"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAABLJJREFUaAXVWt1OE0EUbosB+QnQeAEBjQ0hqDdYjSiXveIS6BO0fQLxlhvhBQiGB6DyAuo9QfROQ9I2hBgaNDWGH6MilX8Q8Ps2O812u7PsbgdYJ1lm98w5Z75v5szZ6SzBgILSitLY2Dh0dnYWCQaDMb2OGF1DVkBbAfU8693d3TdbKEYdL/dBL0a0Iej6+voEwCRxRb34AZksrvT+/v5Lr2RcE2hvb4/U1NQ8BeAkeXgBbmHDmUifnJy82NjYKFi0S0WuCHR0dDzHaI/AmyrgZmBbmJHJtbW1cXOD7NkRgc7OzigcT3sNFVnnMjlD6/T0NO5kNkIyJ0IO8Encv70s8OyXfSFMM3rfFElLjbQFDbqDadxet9O7oDb2Odzc3Px1e3s7K+tDSsAAXmZ7WXJbEpZrwEfgS4OEdRHH4n5dEug3FQQAPoq2t7iUZZpQKBTo7u7+0N/fn+/q6gq3tbU1wX/w8PDwbz6f/7GysnJvfX39+uLi4h0dl1W1hTT7wLywr5k19WyjBHxdXV1xYmIiMzg42IuF+QR98bIsIPC+r6/PjkArBuIVjB8YHZQRQJ4fU5Vt8JYuZjKZz01NTTFjhzb352ZEYiNGhNKY8FMy4hsWCnzDVl0wUsWFhYVPAP+wamcmB8RIrEJcIoC8OwKhktCZmprKtLS09ItOHNanDvUYSkmhqxHgxgyChBBWUyNv/xkaGnpUjY/zbDkLOuaAtgYQr0kYKRn9eDy+DF9954FA+3fsQH8iaRxTd2lpad+BjVDh9n0Y9mmNABgpGX16HxgYOBO9WNUA/DuVShVmZ2eZTdqsdJzI4IfrNX2NUwECUSdGTnR6enq0EZXpJhKJwtzcXFkqlOnayYmZ2EOcCjtFt221tbUNMpvj4+MvKsAL/w0NDTEuYmWjT8cYmVJmEx2JemdnZ1vcK6qjF0FAig1xa7s+pIaSBgxWLASftyXtvhcTewgsIr5HKgFI7NJ4ldj4ThzE9tlTXGIb/A1Z4JYqRqOjox9nZmYeu/XnmxnAzrXZLXjqcxF/9WKo2mZ5efmuW5/EzkVccGuoWh8vuG9HR0eu3RI7Qyjr2lKxATZlGx5dZhlC8x6NlZlhJ+r0t0BZn8QewgnYlc8AMtpeGTKHD8QepC5SKUncd2hnq4aThVw4HLb0tbm5me3t7VW198qtrq5qe6EAmKRtUfmwUWDW3gM4nyeBog9xyiAVdcwBjQCyAI+1X8u0/SYnVmImrtKbeG9vbwTP/8MsFHWs2riWCJARmE1qUh//IUZiFRBLBCjQT7xyotGHdc54Kkd8ZQR0wEnUfgwlYiK2slJBALk1i2lKlmn54IGYiM0MpYIAFfRz+JRZ+QqfUzqmCgiWBKgFtmlUfiCR0rEATmWREqCqgcRVrIkiwiZuB54YbQkYSMRwf5nZKYevMVFZ2BCXKOcSoCJGIYuL34rH8XiRs8FRH2df5k9JArC5dkRAGDEH4580Inh+IWSKag04fbMPNz5dEaBjvgUxQiPoLIwd4TOIqgkt2qYEcOMbln05KWXfyJwYCB12hsKtxyRPiXnQit+osYODg5uQ8bohdPX6F9ryuH+HMJnHfmaeDkw6rh//AbFw/GAvX5JeAAAAAElFTkSuQmCC" alt="Facebook" width="24" height="24"/></a></div></nav><button type="button" class="HeaderNavButton__Wrapper-sc-giz7fq-0 eChxWj"><div class="HeaderNavButton__Line-sc-giz7fq-1 jpcQJX"></div><div class="HeaderNavButton__Line-sc-giz7fq-1 jpcQJX"></div><div class="HeaderNavButton__Line-sc-giz7fq-1 jpcQJX"></div></button></div></header><nav class="HeaderNavSp__Wrapper-sc-14jg0n6-0 hUVZkP"><div class="HeaderNavLinks__Wrapper-sc-df9m31-0 bubIBK"><h2 class="NavLinkHeading__Text-sc-9g8hpt-0 gPnRce">ABOUT</h2><ul class="HeaderNavLinks__LinkList-sc-df9m31-1 kGEgB"><li class="HeaderNavLinks__LinkItem-sc-df9m31-3 hWqcld"><a class="NavLink__StyledLink-sc-12swpe6-0 cZIIUC" href="/about/">POSTDについて</a></li><li class="HeaderNavLinks__LinkItem-sc-df9m31-3 hWqcld"><a href="https://www.nijibox.jp/contacts/contact-form1" target="_blank" rel="noopener noreferrer" class="NavLink__ExternalLink-sc-12swpe6-1 ORlYd">お問い合わせ</a></li><li class="HeaderNavLinks__LinkItem-sc-df9m31-3 hWqcld"><a class="NavLink__StyledLink-sc-12swpe6-0 cZIIUC" href="/about/terms/">利用規約</a></li><li class="HeaderNavLinks__LinkItem-sc-df9m31-3 hWqcld"><a href="https://cdn.p.recruit.co.jp/terms/njb-t-1001/index.html" target="_blank" rel="noopener noreferrer" class="NavLink__ExternalLink-sc-12swpe6-1 ORlYd">プライバシーポリシー</a></li><li class="HeaderNavLinks__LinkItem-sc-df9m31-3 hWqcld"><a href="https://www.recruit.co.jp/privacy/personaldata/" target="_blank" rel="noopener noreferrer" class="NavLink__ExternalLink-sc-12swpe6-1 ORlYd">パーソナルデータ指針</a></li></ul></div><div class="HeaderNavLinks__Wrapper-sc-df9m31-0 bubIBK"><h2 class="NavLinkHeading__Text-sc-9g8hpt-0 gPnRce">CATEGORY</h2><ul class="HeaderNavLinks__LinkList-sc-df9m31-1 kGEgB"><li class="HeaderNavLinks__LinkItem-sc-df9m31-3 hWqcld"><a class="NavLink__StyledLink-sc-12swpe6-0 cZIIUC" href="/category/design/">デザイン</a></li><li class="HeaderNavLinks__LinkItem-sc-df9m31-3 hWqcld"><a class="NavLink__StyledLink-sc-12swpe6-0 cZIIUC" href="/category/startups/">スタートアップ</a></li><li class="HeaderNavLinks__LinkItem-sc-df9m31-3 hWqcld"><a class="NavLink__StyledLink-sc-12swpe6-0 cZIIUC" href="/category/products/">プロダクト・サービス</a></li><li class="HeaderNavLinks__LinkItem-sc-df9m31-3 hWqcld"><a class="NavLink__StyledLink-sc-12swpe6-0 cZIIUC" href="/category/computer-science/">コンピュータサイエンス</a></li><li class="HeaderNavLinks__LinkItem-sc-df9m31-3 hWqcld"><a class="NavLink__StyledLink-sc-12swpe6-0 cZIIUC" href="/category/careers/">キャリア・働き方</a></li><li class="HeaderNavLinks__LinkItem-sc-df9m31-3 hWqcld"><a class="NavLink__StyledLink-sc-12swpe6-0 cZIIUC" href="/category/programming/">プログラミング</a></li><li class="HeaderNavLinks__LinkItem-sc-df9m31-3 hWqcld"><a class="NavLink__StyledLink-sc-12swpe6-0 cZIIUC" href="/category/infrastructure/">インフラ・ミドルウェア</a></li><li class="HeaderNavLinks__LinkItem-sc-df9m31-3 hWqcld"><a class="NavLink__StyledLink-sc-12swpe6-0 cZIIUC" href="/category/system-development/">開発手法・プロジェクト管理</a></li></ul></div><div class="HeaderNavLinks__Wrapper-sc-df9m31-0 bubIBK"><h2 class="NavLinkHeading__Text-sc-9g8hpt-0 gPnRce">PICK UP タグ</h2><ul class="HeaderNavLinks__TagLinkList-sc-df9m31-2 kJcagp"><li class="HeaderNavLinks__TagLinkItem-sc-df9m31-4 pbhGK"><a class="NavLink__StyledLink-sc-12swpe6-0 NavLink__TagLink-sc-12swpe6-2 cZIIUC kjavfV" href="/tag/javascript/">#JavaScript</a></li><li class="HeaderNavLinks__TagLinkItem-sc-df9m31-4 pbhGK"><a class="NavLink__StyledLink-sc-12swpe6-0 NavLink__TagLink-sc-12swpe6-2 cZIIUC kjavfV" href="/tag/react/">#React</a></li><li class="HeaderNavLinks__TagLinkItem-sc-df9m31-4 pbhGK"><a class="NavLink__StyledLink-sc-12swpe6-0 NavLink__TagLink-sc-12swpe6-2 cZIIUC kjavfV" href="/tag/google/">#Google</a></li><li class="HeaderNavLinks__TagLinkItem-sc-df9m31-4 pbhGK"><a class="NavLink__StyledLink-sc-12swpe6-0 NavLink__TagLink-sc-12swpe6-2 cZIIUC kjavfV" href="/tag/ui-design/">#UIデザイン</a></li><li class="HeaderNavLinks__TagLinkItem-sc-df9m31-4 pbhGK"><a class="NavLink__StyledLink-sc-12swpe6-0 NavLink__TagLink-sc-12swpe6-2 cZIIUC kjavfV" href="/tag/software-architecture/">#ソフトウェアアーキテクチャ</a></li><li class="HeaderNavLinks__TagLinkItem-sc-df9m31-4 pbhGK"><a class="NavLink__StyledLink-sc-12swpe6-0 NavLink__TagLink-sc-12swpe6-2 cZIIUC kjavfV" href="/tag/nodejs/">#NodeJS</a></li><li class="HeaderNavLinks__TagLinkItem-sc-df9m31-4 pbhGK"><a class="NavLink__StyledLink-sc-12swpe6-0 NavLink__TagLink-sc-12swpe6-2 cZIIUC kjavfV" href="/tag/productivity/">#生産性</a></li><li class="HeaderNavLinks__TagLinkItem-sc-df9m31-4 pbhGK"><a class="NavLink__StyledLink-sc-12swpe6-0 NavLink__TagLink-sc-12swpe6-2 cZIIUC kjavfV" href="/tag/performance/">#パフォーマンス</a></li><li class="HeaderNavLinks__TagLinkItem-sc-df9m31-4 pbhGK"><a class="NavLink__StyledLink-sc-12swpe6-0 NavLink__TagLink-sc-12swpe6-2 cZIIUC kjavfV" href="/tag/data-science/">#データサイエンス</a></li><li class="HeaderNavLinks__TagLinkItem-sc-df9m31-4 pbhGK"><a class="NavLink__StyledLink-sc-12swpe6-0 NavLink__TagLink-sc-12swpe6-2 cZIIUC kjavfV" href="/tag/agile/">#アジャイル</a></li><li class="HeaderNavLinks__TagLinkItem-sc-df9m31-4 pbhGK"><a class="NavLink__StyledLink-sc-12swpe6-0 NavLink__TagLink-sc-12swpe6-2 cZIIUC kjavfV" href="/tag/summary/">#まとめ</a></li><li class="HeaderNavLinks__TagLinkItem-sc-df9m31-4 pbhGK"><a class="NavLink__StyledLink-sc-12swpe6-0 NavLink__TagLink-sc-12swpe6-2 cZIIUC kjavfV" href="/tag/engineer-employment/">#エンジニア採用</a></li></ul><div class="HeaderNavLinks__MoreLinkWrapper-sc-df9m31-5 bRPEEh"><a class="NavLink__StyledLink-sc-12swpe6-0 NavLink__MoreLink-sc-12swpe6-3 cZIIUC jYwaN" href="/tag/">タグ一覧を見る</a></div></div><div class="HeaderNavSp__IconWrapper-sc-14jg0n6-1 hWYlUd"><div class="HeaderIcons__Wrapper-sc-fl6baq-0 hyUZWO"><a href="https://feedly.com/i/subscription/feed%2Fhttps%3A%2F%2Fpostd.cc%2Ffeed%2F" target="_blank" rel="noopener noreferrer" class="HeaderIconLink__ExternalLink-sc-nsmdxc-0 egfLUA"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAA5BJREFUaAXtWLFSGzEQ5bh4JmODB6g8doHp0iV/QNylCyUddpmOdOkSunSZfAFHBx18QfwHoU1HCuw2HsYeGtt57+bEyHfSnfbuTMyEnfFIWmlX70larc5ra8/yvAL/9wp4y6DfarWO5vP5sed5byL/fZTB7e3tWdnzlU6g2WyeAnjXBBSkgsFg0DP15dX5eQ1NdmngOZ47srm52b67u7sy2efRlUYgC7wCVzaJUgi4gl8GiUIxsAWpVqs/tGBVGJ3KMmIi9w4UBU+GZRynXDtQBnh9i7AT15PJpPMHoutd6mICZYNXIPOSEBGQggeoEwLEUfmsgKaVeUi8SHOo90nBw7aHpBXQBzLzDYpT1tOEMcFLAWOcj5NTEOcBj2dDoMAicV3X6/XfaB8ona0EiUalUnnn+/7FPcQ2TukzCRQFryYiCWThPa6y0tlKCYnUGCgLPIHiGBE4j8cW2y7iEhNWAv8avCKYRcJIYFXAu5BIEFg18FkkFgisKvg0Eg8EVh28jURI4KmAN5FYXyZ43CBX/KmJyyqZS6KMvebv7Ox8guLQ0XlPz7C6TfyeB/AzPCUOkcDOXROY7i+rzmS3sbEx8uH8GxtZBuiXgu8qnyBxuQwS8N/wsHJzNVFK+R0rf2zqt6x81zQWn56XWKz3pr68unUXQxyHfcZKfKwEfKPRaMP+ddxHwfZo3SXIsGph0OgkJOA5Fq/Ln/DTLgh4wRzY+x5W5i2c85GVKTC4waAAvzbAHKAMdwV6BmwX7YTEiSYGFFBMp9NOmAcwSRd+TvP4AvgTgP9isl0meMwXXirh94Dkg0MHOpvNPg6Hw6+6TtUfAzznenhKsCHdifF4vG36J+GxwBPzwi0UJakeO1yE2VAPbNo8JnjOl/iklBwnBPLC92scPOKDz4hfGPeKkxUUYyJdOEL6BNLjpNuyrt9MSGABSBzFxwjaRvC0T+yAcirZCWWjSh08dQWfElbw9G3dAXZSpDvBY4NrlTkiIfDVh3I/0WFXpIKn2UIQm/xIAxs+duOBTb/UgdyuaQ6LLhM87TIJcJCEBM564tlB8NHf8G36cxAn8PSTeYT0ySTHCat9DdvLyP6AxHRfKXVn8PQhIkADCQmOF4oIPH1bbyHbxEVuJ5vPSC8GTzsxARppJDpovqSugIxg+yGKM7GbXAQ4C0nUarVznO1t/PagkhIZIU4u8CA8xIOwT5/P8hRX4C/0uyMrvpz0RwAAAABJRU5ErkJggg==" alt="Feedly" width="24" height="24"/></a><a href="https://postd.cc/feed/" target="_blank" rel="noopener noreferrer" class="HeaderIconLink__ExternalLink-sc-nsmdxc-0 egfLUA"><img src="data:image/png;base64,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" alt="RSS" width="24" height="24"/></a><a href="https://twitter.com/POSTDcc" target="_blank" rel="noopener noreferrer" class="HeaderIconLink__ExternalLink-sc-nsmdxc-0 egfLUA"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAVmSURBVHgBzVm7UhtJFL2SoEpbvOSCQLyqRObMkHkzKcMZZOsIyHYj5C9AZHZkKVtHEpkdGaJ1hsg2Ywg38pj3ZjIQYJ4+Z9wzNRo9puch4FRJ6mn19Nzue+7p2z0JiQG5XC5zfX29gOKL+/v7HH5nk8lkBuWM3QZlM5FImCga+Oz19/fXTUAiIiEhQaOvrq5WYVQel3kJBw6mEmUwgQdgG44ZLrpnOAbUMJD1oAMJNICJiYm1HhjeBPRdOj4+XtdtrzUAzHoOHP+M4qw8DEx4o6DjjaRfg8nJyaWbm5tdeTjjCU7YLjy+4Ncw1e1PUgZBWkYxLQ+PNJ79x9DQkJyfn+90atRxAMr4kjwyqHLdBtF2AHQdbvxbngg4iOHhYROD2Gv5z1vBgCXne6k0IdFAYM95A7sliBE820/QeCKjlLAJTRRSvPeN/EdEdmRkJHF2dla3KxwKKa3/6tcDvLOIhWaz3X9TU1Ml/L8mwbBxdHS0DLmmTO9qtCeVZsCkBi8cDwwMDLwXDa2Hh+ZHR0c/NQA8dBnBNcsP6hr7+/ubKNODWdGDAeNfcfLu7u7+wbUOddOYpB+2F6wYYAf4WRY9kItVu4wPy1W77vb2dhGDbGj0Y7Kt8vw2zRBNYACrzMlYtjyA2eesBeF+bnBw8DuoVMaM59XDrbrT09Mv0O0fuJ6X7sYX0NbEs2n8cwkGxwtWDIAKYVIFS9YuLy+lr6/PLbtzoIWBPmlYvsO9dhvStijhUEcfhYRu8HbrBIbQiPeqzlQDy3gGZuMN7inHsdLjOc9SIejjhkMlyBs9SCpkEJDpk5OTT14qweB1GP8WarWKy7cSHf8l0FmZQSHRMIfZMJlBigpGGFs4PDysu6hUgfHFAHKpg0oSxr+Q6KhSl2H0il2BfqtUCgQr60i1olK7zxITuP9Owc0lPDhq6pCFGmVg5AdQ6RmuX+JD45+DSh+QhG2EkUs/wO50El85iQdF0DGPwC2hbKoHLIyPj1sqo04tchIvMglw8l7ig6VAyGZn4d5tVWfJLX/dMRIXfLeUAUGarDF4qTiqzlq5vTESF1LgLF0c55bxJeJhC/Hw0btKQ24/umIkFiSh2Tp5SxBQLnlgxbxoxc6LcByzRgl1x0gMMNFv0pD4YNhyyTSBuQ5iwaGS/Er8JC4q8agyBTf/LvG4lAnaq7GxsYySy3lI9B5oU3NRKctV2iO3UbBFFVoWNTMRYGWX6XTaqzSOAkGZvtp5kWuVjnretJLEAzYlAhTHF0kXGFmVZpl0FIht7ErXKq27d2gL3F9PYWN16XJxYCCG/sJsfmF2ics/2zRpp0BM+LJYpTc09g6dYOD+d9Y6gFnYCdGBlV0eHBzU/FJjKhAD26NA3AcvMbVGuS7BUbFs4Bfd6eaobgdUHHUIppOgWXsHphveVbrNpsgXoM8MaWttKRWNfhPNFxUwmMa85qziodyM6yyEbiol1LPSoNIsqFAJSKUa6WfZ4vSu7wVTKUsmRHbJgC3YC50XPttQB/bss9x0tKh5rlODB76h3ZKEC3wD92+1+0O9X1vqdjPjDqJRcq69DWLQ5l7ChPdm3BUt2WhUbe4VaBMXS299y/H6xcVFAwH1v4Tf6PcEoNdrBO6/3vq27wewBTRcSvHoUKcZbd9XdHxDw1OvpzAIb9C2/C8+mJ6eXmDu8tDvDMh5fN5wpe/aTjSQzWZzqVQq1hMFHxgUE1vruyElGmBgIy4qvaaUmvV3XOX5TK17JCCUN0ris+AEgZLtCvKhsv3iQvteCQk1kDwevor4CLXwMafCz04Yw50+JAbYg5FfKziPKnPiihfOMAZJehj4/YYqgxupsEa78RMK9vsn6EQJOAAAAABJRU5ErkJggg==" alt="Twitter" width="24" height="24"/></a><a href="https://www.facebook.com/postdcc" target="_blank" rel="noopener noreferrer" class="HeaderIconLink__ExternalLink-sc-nsmdxc-0 egfLUA"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAABLJJREFUaAXVWt1OE0EUbosB+QnQeAEBjQ0hqDdYjSiXveIS6BO0fQLxlhvhBQiGB6DyAuo9QfROQ9I2hBgaNDWGH6MilX8Q8Ps2O812u7PsbgdYJ1lm98w5Z75v5szZ6SzBgILSitLY2Dh0dnYWCQaDMb2OGF1DVkBbAfU8693d3TdbKEYdL/dBL0a0Iej6+voEwCRxRb34AZksrvT+/v5Lr2RcE2hvb4/U1NQ8BeAkeXgBbmHDmUifnJy82NjYKFi0S0WuCHR0dDzHaI/AmyrgZmBbmJHJtbW1cXOD7NkRgc7OzigcT3sNFVnnMjlD6/T0NO5kNkIyJ0IO8Encv70s8OyXfSFMM3rfFElLjbQFDbqDadxet9O7oDb2Odzc3Px1e3s7K+tDSsAAXmZ7WXJbEpZrwEfgS4OEdRHH4n5dEug3FQQAPoq2t7iUZZpQKBTo7u7+0N/fn+/q6gq3tbU1wX/w8PDwbz6f/7GysnJvfX39+uLi4h0dl1W1hTT7wLywr5k19WyjBHxdXV1xYmIiMzg42IuF+QR98bIsIPC+r6/PjkArBuIVjB8YHZQRQJ4fU5Vt8JYuZjKZz01NTTFjhzb352ZEYiNGhNKY8FMy4hsWCnzDVl0wUsWFhYVPAP+wamcmB8RIrEJcIoC8OwKhktCZmprKtLS09ItOHNanDvUYSkmhqxHgxgyChBBWUyNv/xkaGnpUjY/zbDkLOuaAtgYQr0kYKRn9eDy+DF9954FA+3fsQH8iaRxTd2lpad+BjVDh9n0Y9mmNABgpGX16HxgYOBO9WNUA/DuVShVmZ2eZTdqsdJzI4IfrNX2NUwECUSdGTnR6enq0EZXpJhKJwtzcXFkqlOnayYmZ2EOcCjtFt221tbUNMpvj4+MvKsAL/w0NDTEuYmWjT8cYmVJmEx2JemdnZ1vcK6qjF0FAig1xa7s+pIaSBgxWLASftyXtvhcTewgsIr5HKgFI7NJ4ldj4ThzE9tlTXGIb/A1Z4JYqRqOjox9nZmYeu/XnmxnAzrXZLXjqcxF/9WKo2mZ5efmuW5/EzkVccGuoWh8vuG9HR0eu3RI7Qyjr2lKxATZlGx5dZhlC8x6NlZlhJ+r0t0BZn8QewgnYlc8AMtpeGTKHD8QepC5SKUncd2hnq4aThVw4HLb0tbm5me3t7VW198qtrq5qe6EAmKRtUfmwUWDW3gM4nyeBog9xyiAVdcwBjQCyAI+1X8u0/SYnVmImrtKbeG9vbwTP/8MsFHWs2riWCJARmE1qUh//IUZiFRBLBCjQT7xyotGHdc54Kkd8ZQR0wEnUfgwlYiK2slJBALk1i2lKlmn54IGYiM0MpYIAFfRz+JRZ+QqfUzqmCgiWBKgFtmlUfiCR0rEATmWREqCqgcRVrIkiwiZuB54YbQkYSMRwf5nZKYevMVFZ2BCXKOcSoCJGIYuL34rH8XiRs8FRH2df5k9JArC5dkRAGDEH4580Inh+IWSKag04fbMPNz5dEaBjvgUxQiPoLIwd4TOIqgkt2qYEcOMbln05KWXfyJwYCB12hsKtxyRPiXnQit+osYODg5uQ8bohdPX6F9ryuH+HMJnHfmaeDkw6rh//AbFw/GAvX5JeAAAAAElFTkSuQmCC" alt="Facebook" width="24" height="24"/></a></div></div><div class="HeaderNavSp__CorpWrapper-sc-14jg0n6-2 egqDVK"><div class="HeaderCorpInfo__Wrapper-sc-1k2ubzo-0 kUpMwN"><img src="data:image/png;base64,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" alt="NIJIBOX" width="100" height="37"/><div class="HeaderCorpInfo__CopyrightWrapper-sc-1k2ubzo-1 kHPENY"><small class="Copyright__Text-sc-1yjjwtv-0 dOgXOf">©NIJIBOX CO.,LTD ALL RIGHTS RESERVED</small></div></div></div></nav><div class="StickyHeader__Wrapper-sc-1tro7id-0 iFioks"><div class="StickyHeader__Inner-sc-1tro7id-1 ipFjCB"><div class="HeaderLeftSide__Wrapper-sc-151me4h-0 icgTxN"><a href="/"><h1 class="HeaderLogo__Pc-sc-128t2eb-0 kITRPe"><img src="/static/logo-10ab68d2ba3b6095a7c9c0d4ce901428.png" alt="POSTD PRODUCED BY NIJIBOX" width="160" height="75"/></h1><h1 class="HeaderLogo__Sp-sc-128t2eb-1 iNZNRU"><img src="/static/logo-10ab68d2ba3b6095a7c9c0d4ce901428.png" alt="POSTD PRODUCED BY NIJIBOX" width="96" height="45"/></h1></a><div class="HeaderLeftSide__DescriptionWrapper-sc-151me4h-1 iteQnd"><p class="HeaderDescription__Text-sc-clsdq0-0 iQWsBp">ニジボックスが運営する<br/>エンジニアに向けた<br/>キュレーションメディア</p></div></div><div class="HeaderIcons__Wrapper-sc-fl6baq-0 hyUZWO"><a href="https://feedly.com/i/subscription/feed%2Fhttps%3A%2F%2Fpostd.cc%2Ffeed%2F" target="_blank" rel="noopener noreferrer" class="HeaderIconLink__ExternalLink-sc-nsmdxc-0 egfLUA"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAA5BJREFUaAXtWLFSGzEQ5bh4JmODB6g8doHp0iV/QNylCyUddpmOdOkSunSZfAFHBx18QfwHoU1HCuw2HsYeGtt57+bEyHfSnfbuTMyEnfFIWmlX70larc5ra8/yvAL/9wp4y6DfarWO5vP5sed5byL/fZTB7e3tWdnzlU6g2WyeAnjXBBSkgsFg0DP15dX5eQ1NdmngOZ47srm52b67u7sy2efRlUYgC7wCVzaJUgi4gl8GiUIxsAWpVqs/tGBVGJ3KMmIi9w4UBU+GZRynXDtQBnh9i7AT15PJpPMHoutd6mICZYNXIPOSEBGQggeoEwLEUfmsgKaVeUi8SHOo90nBw7aHpBXQBzLzDYpT1tOEMcFLAWOcj5NTEOcBj2dDoMAicV3X6/XfaB8ona0EiUalUnnn+/7FPcQ2TukzCRQFryYiCWThPa6y0tlKCYnUGCgLPIHiGBE4j8cW2y7iEhNWAv8avCKYRcJIYFXAu5BIEFg18FkkFgisKvg0Eg8EVh28jURI4KmAN5FYXyZ43CBX/KmJyyqZS6KMvebv7Ox8guLQ0XlPz7C6TfyeB/AzPCUOkcDOXROY7i+rzmS3sbEx8uH8GxtZBuiXgu8qnyBxuQwS8N/wsHJzNVFK+R0rf2zqt6x81zQWn56XWKz3pr68unUXQxyHfcZKfKwEfKPRaMP+ddxHwfZo3SXIsGph0OgkJOA5Fq/Ln/DTLgh4wRzY+x5W5i2c85GVKTC4waAAvzbAHKAMdwV6BmwX7YTEiSYGFFBMp9NOmAcwSRd+TvP4AvgTgP9isl0meMwXXirh94Dkg0MHOpvNPg6Hw6+6TtUfAzznenhKsCHdifF4vG36J+GxwBPzwi0UJakeO1yE2VAPbNo8JnjOl/iklBwnBPLC92scPOKDz4hfGPeKkxUUYyJdOEL6BNLjpNuyrt9MSGABSBzFxwjaRvC0T+yAcirZCWWjSh08dQWfElbw9G3dAXZSpDvBY4NrlTkiIfDVh3I/0WFXpIKn2UIQm/xIAxs+duOBTb/UgdyuaQ6LLhM87TIJcJCEBM564tlB8NHf8G36cxAn8PSTeYT0ySTHCat9DdvLyP6AxHRfKXVn8PQhIkADCQmOF4oIPH1bbyHbxEVuJ5vPSC8GTzsxARppJDpovqSugIxg+yGKM7GbXAQ4C0nUarVznO1t/PagkhIZIU4u8CA8xIOwT5/P8hRX4C/0uyMrvpz0RwAAAABJRU5ErkJggg==" alt="Feedly" width="24" height="24"/></a><a href="https://postd.cc/feed/" target="_blank" rel="noopener noreferrer" class="HeaderIconLink__ExternalLink-sc-nsmdxc-0 egfLUA"><img src="data:image/png;base64,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" alt="RSS" width="24" height="24"/></a><a href="https://twitter.com/POSTDcc" target="_blank" rel="noopener noreferrer" class="HeaderIconLink__ExternalLink-sc-nsmdxc-0 egfLUA"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAVmSURBVHgBzVm7UhtJFL2SoEpbvOSCQLyqRObMkHkzKcMZZOsIyHYj5C9AZHZkKVtHEpkdGaJ1hsg2Ywg38pj3ZjIQYJ4+Z9wzNRo9puch4FRJ6mn19Nzue+7p2z0JiQG5XC5zfX29gOKL+/v7HH5nk8lkBuWM3QZlM5FImCga+Oz19/fXTUAiIiEhQaOvrq5WYVQel3kJBw6mEmUwgQdgG44ZLrpnOAbUMJD1oAMJNICJiYm1HhjeBPRdOj4+XtdtrzUAzHoOHP+M4qw8DEx4o6DjjaRfg8nJyaWbm5tdeTjjCU7YLjy+4Ncw1e1PUgZBWkYxLQ+PNJ79x9DQkJyfn+90atRxAMr4kjwyqHLdBtF2AHQdbvxbngg4iOHhYROD2Gv5z1vBgCXne6k0IdFAYM95A7sliBE820/QeCKjlLAJTRRSvPeN/EdEdmRkJHF2dla3KxwKKa3/6tcDvLOIhWaz3X9TU1Ml/L8mwbBxdHS0DLmmTO9qtCeVZsCkBi8cDwwMDLwXDa2Hh+ZHR0c/NQA8dBnBNcsP6hr7+/ubKNODWdGDAeNfcfLu7u7+wbUOddOYpB+2F6wYYAf4WRY9kItVu4wPy1W77vb2dhGDbGj0Y7Kt8vw2zRBNYACrzMlYtjyA2eesBeF+bnBw8DuoVMaM59XDrbrT09Mv0O0fuJ6X7sYX0NbEs2n8cwkGxwtWDIAKYVIFS9YuLy+lr6/PLbtzoIWBPmlYvsO9dhvStijhUEcfhYRu8HbrBIbQiPeqzlQDy3gGZuMN7inHsdLjOc9SIejjhkMlyBs9SCpkEJDpk5OTT14qweB1GP8WarWKy7cSHf8l0FmZQSHRMIfZMJlBigpGGFs4PDysu6hUgfHFAHKpg0oSxr+Q6KhSl2H0il2BfqtUCgQr60i1olK7zxITuP9Owc0lPDhq6pCFGmVg5AdQ6RmuX+JD45+DSh+QhG2EkUs/wO50El85iQdF0DGPwC2hbKoHLIyPj1sqo04tchIvMglw8l7ig6VAyGZn4d5tVWfJLX/dMRIXfLeUAUGarDF4qTiqzlq5vTESF1LgLF0c55bxJeJhC/Hw0btKQ24/umIkFiSh2Tp5SxBQLnlgxbxoxc6LcByzRgl1x0gMMNFv0pD4YNhyyTSBuQ5iwaGS/Er8JC4q8agyBTf/LvG4lAnaq7GxsYySy3lI9B5oU3NRKctV2iO3UbBFFVoWNTMRYGWX6XTaqzSOAkGZvtp5kWuVjnretJLEAzYlAhTHF0kXGFmVZpl0FIht7ErXKq27d2gL3F9PYWN16XJxYCCG/sJsfmF2ics/2zRpp0BM+LJYpTc09g6dYOD+d9Y6gFnYCdGBlV0eHBzU/FJjKhAD26NA3AcvMbVGuS7BUbFs4Bfd6eaobgdUHHUIppOgWXsHphveVbrNpsgXoM8MaWttKRWNfhPNFxUwmMa85qziodyM6yyEbiol1LPSoNIsqFAJSKUa6WfZ4vSu7wVTKUsmRHbJgC3YC50XPttQB/bss9x0tKh5rlODB76h3ZKEC3wD92+1+0O9X1vqdjPjDqJRcq69DWLQ5l7ChPdm3BUt2WhUbe4VaBMXS299y/H6xcVFAwH1v4Tf6PcEoNdrBO6/3vq27wewBTRcSvHoUKcZbd9XdHxDw1OvpzAIb9C2/C8+mJ6eXmDu8tDvDMh5fN5wpe/aTjSQzWZzqVQq1hMFHxgUE1vruyElGmBgIy4qvaaUmvV3XOX5TK17JCCUN0ris+AEgZLtCvKhsv3iQvteCQk1kDwevor4CLXwMafCz04Yw50+JAbYg5FfKziPKnPiihfOMAZJehj4/YYqgxupsEa78RMK9vsn6EQJOAAAAABJRU5ErkJggg==" alt="Twitter" width="24" height="24"/></a><a href="https://www.facebook.com/postdcc" target="_blank" rel="noopener noreferrer" class="HeaderIconLink__ExternalLink-sc-nsmdxc-0 egfLUA"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAABLJJREFUaAXVWt1OE0EUbosB+QnQeAEBjQ0hqDdYjSiXveIS6BO0fQLxlhvhBQiGB6DyAuo9QfROQ9I2hBgaNDWGH6MilX8Q8Ps2O812u7PsbgdYJ1lm98w5Z75v5szZ6SzBgILSitLY2Dh0dnYWCQaDMb2OGF1DVkBbAfU8693d3TdbKEYdL/dBL0a0Iej6+voEwCRxRb34AZksrvT+/v5Lr2RcE2hvb4/U1NQ8BeAkeXgBbmHDmUifnJy82NjYKFi0S0WuCHR0dDzHaI/AmyrgZmBbmJHJtbW1cXOD7NkRgc7OzigcT3sNFVnnMjlD6/T0NO5kNkIyJ0IO8Encv70s8OyXfSFMM3rfFElLjbQFDbqDadxet9O7oDb2Odzc3Px1e3s7K+tDSsAAXmZ7WXJbEpZrwEfgS4OEdRHH4n5dEug3FQQAPoq2t7iUZZpQKBTo7u7+0N/fn+/q6gq3tbU1wX/w8PDwbz6f/7GysnJvfX39+uLi4h0dl1W1hTT7wLywr5k19WyjBHxdXV1xYmIiMzg42IuF+QR98bIsIPC+r6/PjkArBuIVjB8YHZQRQJ4fU5Vt8JYuZjKZz01NTTFjhzb352ZEYiNGhNKY8FMy4hsWCnzDVl0wUsWFhYVPAP+wamcmB8RIrEJcIoC8OwKhktCZmprKtLS09ItOHNanDvUYSkmhqxHgxgyChBBWUyNv/xkaGnpUjY/zbDkLOuaAtgYQr0kYKRn9eDy+DF9954FA+3fsQH8iaRxTd2lpad+BjVDh9n0Y9mmNABgpGX16HxgYOBO9WNUA/DuVShVmZ2eZTdqsdJzI4IfrNX2NUwECUSdGTnR6enq0EZXpJhKJwtzcXFkqlOnayYmZ2EOcCjtFt221tbUNMpvj4+MvKsAL/w0NDTEuYmWjT8cYmVJmEx2JemdnZ1vcK6qjF0FAig1xa7s+pIaSBgxWLASftyXtvhcTewgsIr5HKgFI7NJ4ldj4ThzE9tlTXGIb/A1Z4JYqRqOjox9nZmYeu/XnmxnAzrXZLXjqcxF/9WKo2mZ5efmuW5/EzkVccGuoWh8vuG9HR0eu3RI7Qyjr2lKxATZlGx5dZhlC8x6NlZlhJ+r0t0BZn8QewgnYlc8AMtpeGTKHD8QepC5SKUncd2hnq4aThVw4HLb0tbm5me3t7VW198qtrq5qe6EAmKRtUfmwUWDW3gM4nyeBog9xyiAVdcwBjQCyAI+1X8u0/SYnVmImrtKbeG9vbwTP/8MsFHWs2riWCJARmE1qUh//IUZiFRBLBCjQT7xyotGHdc54Kkd8ZQR0wEnUfgwlYiK2slJBALk1i2lKlmn54IGYiM0MpYIAFfRz+JRZ+QqfUzqmCgiWBKgFtmlUfiCR0rEATmWREqCqgcRVrIkiwiZuB54YbQkYSMRwf5nZKYevMVFZ2BCXKOcSoCJGIYuL34rH8XiRs8FRH2df5k9JArC5dkRAGDEH4580Inh+IWSKag04fbMPNz5dEaBjvgUxQiPoLIwd4TOIqgkt2qYEcOMbln05KWXfyJwYCB12hsKtxyRPiXnQit+osYODg5uQ8bohdPX6F9ryuH+HMJnHfmaeDkw6rh//AbFw/GAvX5JeAAAAAElFTkSuQmCC" alt="Facebook" width="24" height="24"/></a></div></div></div><main class="Layout__Wrapper-sc-wljzn2-0 eXXaLr"><section class="Layout__Inner-sc-wljzn2-1 cmfBeF"><div class="page__FullWidthContent-sc-dlpr27-0 OPsHt"><div class="page__LeftColumn-sc-dlpr27-1 elZjqD"><div class="page__Wrapper-sc-dlpr27-2 kdQgRZ"><div class="article__Inner-sc-19k0vly-0 lbIhIM"><p class="ArticleDate__Text-sc-a95f93-0 irjTJi">2024年11月28日</p><div class="ArticleInfo__TitleWrapper-sc-1qj3yjx-0 ksKsDv"><h1 class="ArticleTitle__Text-sc-n1jdqj-0 fxciTM">アルゴリズムのパフォーマンスを段階的に改善する</h1></div><ul class="ArticleInfo__TagList-sc-1qj3yjx-1 lpgjCc"><li class="ArticleInfo__TagItem-sc-1qj3yjx-2 idjGgX"><a class="Tag__StyledLink-sc-1jf1fx3-0 ddvARG" href="/tag/performance/">パフォーマンス</a></li><li class="ArticleInfo__TagItem-sc-1qj3yjx-2 idjGgX"><a class="Tag__StyledLink-sc-1jf1fx3-0 ddvARG" href="/tag/algorithm/">アルゴリズム</a></li><li class="ArticleInfo__TagItem-sc-1qj3yjx-2 idjGgX"><a class="Tag__StyledLink-sc-1jf1fx3-0 ddvARG" href="/tag/rust/">Rust</a></li></ul><img src="/static/4ed810b3d112d772c2cc124b5e8fba5d/mv.png" class="article__MainVisual-sc-19k0vly-1 ikOPxI"/><div class="article__OriginalWrapper-sc-19k0vly-2 hRbWsE"><div class="OriginalInfo__Wrapper-sc-7610xd-0 UTMQN"><div class="OriginalInfo__Content-sc-7610xd-1 dlhUOl"><div class="OriginalInfo__TextArea-sc-7610xd-3 jWRgds"><div class="OriginalInfo__Information-sc-7610xd-4 hulzJL"><a href="https://blog.mapotofu.org/blogs/rabitq-bench/" class="OriginalInfo__ExternalLink-sc-7610xd-7 jPuUmd">Improve an algorithm performance step by step</a><p class="OriginalInfo__Author-sc-7610xd-6 qHERx">(2024-10-12)<!-- -->by<!-- --> <a href="https://blog.mapotofu.org/about/" class="OriginalInfo__ExternalLink-sc-7610xd-7 jPuUmd">Keming Yang</a></p></div><p class="OriginalInfo__Note-sc-7610xd-5 cWvAEW">本記事は、原著者の許諾のもとに翻訳・掲載しております。</p></div></div></div></div><div class="textPageStyles__TextPage-sc-1qtxiy0-0 bNqEXq"><p>最近、筆者は<a href="https://arxiv.org/abs/2405.12497">RaBitQ</a>という新しい近似最近傍探索アルゴリズムを使ったさまざまな試みを行っています。このアルゴリズムを提案した論文の著者はすでに<a href="https://github.com/gaoj0017/RaBitQ">C++実装</a>を提供しており、実行速度はかなり速いです。筆者はこれを<a href="https://github.com/kemingy/rabitq">Rustに書き換えようとしました</a>(いわゆるRiiR(Rewrite it in Rust)です)が、実装結果は元のアルゴリズムよりも大幅に遅いことが判明しました。この記事では、アルゴリズムのパフォーマンスを段階的に改善する方法をご紹介します。</p> <h2>環境の準備</h2> <h3>データセット</h3> <p>最も重要なのは、適当なデータセットをいくつか用意することです。前述の論文では、<code class="language-text">sift_dim128_1m_l2</code>と<code class="language-text">gist_dim960_1m_l2</code>という2つのデータセットについての結果が示されています。このデータセットでは、128項目と960項目というのがよく使われるサイズであり、1,000,000個のデータポイント(ベクトル)があれば性能を測るのに十分だということです。つまり、これらのデータセットを使うことで、アルゴリズムの性能をしっかりと評価できるということです。データセットは<a href="http://corpus-texmex.irisa.fr/">こちら</a>からダウンロードできます。(こちらのサイトはTLSに対応しておらず、FTPダウンロードしか提供していません。)</p> <p>これらのデータセットは、一般的なベクトル形式である<code class="language-text">fvecs/ivecs</code>を使用しています。</p> <div class="gatsby-highlight" data-language="python"><pre style="counter-reset: linenumber NaN" class="language-python line-numbers"><code class="language-python"><span class="token operator">|</span> dim <span class="token punctuation">(</span><span class="token number">4</span> <span class="token builtin">bytes</span><span class="token punctuation">)</span> <span class="token operator">|</span> vector <span class="token punctuation">(</span><span class="token number">4</span> <span class="token operator">*</span> dim <span class="token builtin">bytes</span><span class="token punctuation">)</span> <span class="token operator">|</span> <span class="token operator">|</span> dim <span class="token punctuation">(</span><span class="token number">4</span> <span class="token builtin">bytes</span><span class="token punctuation">)</span> <span class="token operator">|</span> vector <span class="token punctuation">(</span><span class="token number">4</span> <span class="token operator">*</span> dim <span class="token builtin">bytes</span><span class="token punctuation">)</span> <span class="token operator">|</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token operator">|</span> dim <span class="token punctuation">(</span><span class="token number">4</span> <span class="token builtin">bytes</span><span class="token punctuation">)</span> <span class="token operator">|</span> vector <span class="token punctuation">(</span><span class="token number">4</span> <span class="token operator">*</span> dim <span class="token builtin">bytes</span><span class="token punctuation">)</span> <span class="token operator">|</span></code><span aria-hidden="true" class="line-numbers-rows" style="white-space: normal; width: auto; left: 0;"><span></span><span></span><span></span><span></span></span></pre></div> <p>読み取り/書き込み用のスクリプトは筆者の<a href="https://gist.github.com/kemingy/2f503fcfff86b9e0197e975c02359157">Gist</a>から取得できます。</p> <h3>プロファイリングツール</h3> <p>Rustコードのプロファイリングには<a href="https://blog.mapotofu.org/blogs/rabitq-bench/#:~:text=I%20use-,samply,-to%20profile%20the">samply</a>を使用しています。このツールは<a href="https://profiler.firefox.com/">Firefox Profiler</a>に追加して使用できます。プロファイリングの結果は、クラウドにアップロードすることで他者と共有することもできます。こちらは<a href="https://share.firefox.dev/3Y4Hppz">Gistで公開されているC++版のプロファイリング例</a>です。ビューはFlameGraphとCallTreeが最も一般的です。パフォーマンスイベント権限を付与し、mlockの上限を増やす必要があります。</p> <div class="gatsby-highlight" data-language="bash"><pre style="counter-reset: linenumber NaN" class="language-bash line-numbers"><code class="language-bash"><span class="token builtin class-name">echo</span> <span class="token string">'1'</span> <span class="token operator">|</span> <span class="token function">sudo</span> <span class="token function">tee</span> /proc/sys/kernel/perf_event_paranoid <span class="token function">sudo</span> <span class="token function">sysctl</span> <span class="token assign-left variable">kernel.perf_event_mlock_kb</span><span class="token operator">=</span><span class="token number">2048</span></code><span aria-hidden="true" class="line-numbers-rows" style="white-space: normal; width: auto; left: 0;"><span></span><span></span></span></pre></div> <p><a href="https://godbolt.org/">GodBolt</a>のCompiler Explorerも、C++とRustの関数のアセンブリコードを比較するのに役立ちます。</p> <h3>Cargoプロファイル</h3> <p>リリースビルドにデバッグ情報を含めるには、<code class="language-text">Cargo.toml</code>に新たなプロファイルを追加します。</p> <div class="gatsby-highlight" data-language="toml"><pre style="counter-reset: linenumber NaN" class="language-toml line-numbers"><code class="language-toml"><span class="token punctuation">[</span><span class="token table class-name">profile.perf</span><span class="token punctuation">]</span> <span class="token key property">inherits</span> <span class="token punctuation">=</span> <span class="token string">"release"</span> <span class="token key property">debug</span> <span class="token punctuation">=</span> <span class="token boolean">true</span> <span class="token key property">codegen-units</span> <span class="token punctuation">=</span> <span class="token number">16</span></code><span aria-hidden="true" class="line-numbers-rows" style="white-space: normal; width: auto; left: 0;"><span></span><span></span><span></span><span></span></span></pre></div> <p>コンパイルコストとランタイム速度は、プロファイリングにおけるユーザーエクスペリエンスを大きく左右します。</p> <ul> <li><code class="language-text">cargo build</code>はコンパイル速度は速いものの、Pythonよりもコードの実行速度は遅い場合がある</li> <li><code class="language-text">cargo build --release</code>は、コードの実行速度は速いものの、コンパイルには時間がかかる場合がある ベンチマーキングには<code class="language-text">opt-level = 3</code>を使用することを推奨します。 以下の設定の使用が推奨されているのを目にしましたが、筆者の場合はコンパイル速度が遅くなり、パフォーマンスの改善は全く見られませんでした。</li> </ul> <div class="gatsby-highlight" data-language="toml"><pre style="counter-reset: linenumber NaN" class="language-toml line-numbers"><code class="language-toml"><span class="token key property">codegen-units</span> <span class="token punctuation">=</span> <span class="token number">1</span> <span class="token key property">lto</span> <span class="token punctuation">=</span> <span class="token string">"fat"</span> <span class="token key property">panic</span> <span class="token punctuation">=</span> <span class="token string">"abort"</span></code><span aria-hidden="true" class="line-numbers-rows" style="white-space: normal; width: auto; left: 0;"><span></span><span></span><span></span></span></pre></div> <h3>ベンチマークツール</h3> <p><a href="https://github.com/bheisler/criterion.rs">Criterion</a>は、統計に基づく優れたベンチマークツールです。関連するベンチマークコードをすべて格納するために、新たな<a href="https://github.com/kemingy/rs_bench">リポジトリ</a>を作成しました。ベンチマークコードは同じリポジトリに入れる必要があるようです。</p> <p>注目すべき点として、ベンチマークの結果はあまり安定していません。筆者の場合はコードに手を加えていない状態で<code class="language-text">±10%</code>の差異が見られました。ノートパソコンを使用している場合、高温によりCPUがアンダークロックし、さらに差異が広がる可能性があります。</p> <p>関数のベンチマークには、いくつかの異なるパラメータを使用することをおすすめします。この場合、筆者は異なる項目のベクトルを使用します。すべての項目の結果がプラスであれば、通常は改善が効果的であることを意味します。</p> <h3>指標</h3> <p>最初からいくつかの指標を追加しましょう。指標をチェックすることで、多くのバグやパフォーマンスの問題を見つけることができます。筆者は、現行の要件が単純であるため直接<code class="language-text">AtomicU64</code>を使用していますが、後で<a href="https://github.com/prometheus/client_rust">Prometheusを使った指標</a>に移行するかもしれません。 指標/ロギング/トレースが多すぎるとパフォーマンスに影響が出る可能性があるため、これらを追加する際には注意してください。</p> <h3>リソース</h3> <p>ベンチマークの際に、筆者はエンドツーエンドのQPSが極めて不安定であることに気がつきました。コードを再コンパイルしていなくても、翌朝にはベンチマークの結果に<strong>15</strong>%の改善または悪化が見られる場合もあります。また、筆者はVSCodeの拡張機能「rust-analyzer」を使用しているため、CPUが完全にアイドル状態ではなく、CPUの使用率は低いもののベンチマークの結果に大きな影響を及ぼすことが分かりました。ちなみに、筆者は8つの高性能コアと8つの高効率コアで構成された<a href="https://www.intel.com/content/www/us/en/products/sku/230500/intel-core-i713700k-processor-30m-cache-up-to-5-40-ghz/specifications.html">Intel Core i7-13700K</a>を使用しており、プログラムはシングルスレッドです。</p> <p>筆者は<code class="language-text">taskset</code>を使用してプロセスを実行するCPUを指定しています。そうすることで、種類の異なるコアのスケジューリングの影響を受けることはありません。</p> <p>第13〜14世代のIntel Core CPUは電圧が非常に高いため不安定です。筆者はこの問題をBIOSで修正しました。</p> <p>クラウドの仮想マシンはCPU温度の影響を受けないかもしれませんが、クラウドプロバイダーにはCPUのスロットリングやオーバーコミットに関する独自のポリシーがある場合があります。</p> <h2>段階的な改善</h2> <h3>単純な実装から始める</h3> <p>筆者の<a href="https://github.com/kemingy/rabitq/tree/dbfd54bd5d739b0729dc28e6fbd8d5413b019561">最初のリリース</a>は、<a href="https://docs.rs/nalgebra">nalgebra</a>という代数ライブラリをベースにRaBitQアルゴリズムを実装しました。主な理由は、RaBitQアルゴリズムにおいて重要なステップである直交行列を取得するためにQR分解を使う必要があるからです。また、成熟した線形代数ライブラリは行列やベクトルを操作するのに役立つ関数を多く提供するため、アルゴリズムを実装しやすいという利点もあります。Pythonで<code class="language-text">numpy</code>を使わずに行列の乗算、射影、分解に関するアルゴリズムを実装することを考えてみてください。まさに悪夢です。</p> <p><code class="language-text">nalgebra</code>はこのようなシナリオ向けに最適化されているため、パフォーマンスは良いはずだと考えました。しかし、ベンチマークは筆者の予想よりもかなり遅い結果となりました。<code class="language-text">numpy</code>で再実装した方がはるかに速いでしょう:(</p> <p><a href="https://share.firefox.dev/3AwiVNR">プロファイリング</a>によると、<code class="language-text">f32::clone()</code>の呼び出しが多数あります。全体の時間の約33%を占めており、<code class="language-text">query_one</code>関数に注目すると44%となります。この結果から、一部のベクトルについてメモリを事前に割り当て、同じイテレーション内で再利用するという非常に一般的な裏技が使えることが分かります。したがって、<code class="language-text">(x - y).norm_squared()</code>を使う代わりに、<code class="language-text">(x - y)</code>の結果を格納する別のベクトルをあらかじめ宣言する必要があり、結果的に<code class="language-text">x.sub_to(y, &mut z); z.norm_squared()</code>となります。<a href="https://github.com/kemingy/rabitq/commit/23f9aff4c8b3303c0a03ac9a7472ada8cc915a3b">コミット23f9aff</a>をご覧ください。</p> <p>ほとんどの代数ライブラリと同様に、このベクトルは列優先で行列を格納するため、行よりも列に対して処理を順番に繰り返し実行した方が速いことを意味します。イテレーションの前に行列を転置しなくてはならないのは少し面倒であり、ベクトルと行列の乗算がすべてコンパイル時に項目のミスマッチエラー(<code class="language-text">1 x dyn</code>または<code class="language-text">dyn x 1</code>)を検出できるとは限りません。</p> <h3>CPUターゲット</h3> <p>RaBitQは、バイナリの内積距離を用いておおよその距離を推定します。距離は以下により計算します。</p> <div class="gatsby-highlight" data-language="rust"><pre style="counter-reset: linenumber NaN" class="language-rust line-numbers"><code class="language-rust"><span class="token keyword">fn</span> <span class="token function-definition function">binary_dot_product</span><span class="token punctuation">(</span>x<span class="token punctuation">:</span> <span class="token operator">&</span><span class="token punctuation">[</span><span class="token keyword">u64</span><span class="token punctuation">]</span><span class="token punctuation">,</span> y<span class="token punctuation">:</span> <span class="token operator">&</span><span class="token punctuation">[</span><span class="token keyword">u64</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token keyword">u32</span> <span class="token punctuation">{</span> <span class="token macro property">assert_eq!</span><span class="token punctuation">(</span>x<span class="token punctuation">.</span><span class="token function">len</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> y<span class="token punctuation">.</span><span class="token function">len</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token keyword">mut</span> res <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token number">0</span><span class="token punctuation">..</span>x<span class="token punctuation">.</span><span class="token function">len</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> res <span class="token operator">+=</span> <span class="token punctuation">(</span>x<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">&</span> y<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">count_ones</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> res <span class="token punctuation">}</span></code><span aria-hidden="true" class="line-numbers-rows" style="white-space: normal; width: auto; left: 0;"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div> <p>ここでは、<code class="language-text">u64::count_ones()</code>は組み込み関数であるため、通常は特別な設定なしで使用できると考えましたが、実際にはコンパイル時にpopcnt機能を有効化する必要があります。<code class="language-text">RUSTFLAGS="-C target-feature=+popcnt"</code>を使うことで有効化できますが、筆者は<code class="language-text">RUSTFLAGS="-C target-cpu=native"</code>を好みます。後者は現在のCPUが対応するすべてのCPU機能を有効化しますが、バイナリ互換性が失われます。現時点では、特定の環境でのみ使用するため問題ではないと考えています。以下のセクションでも、AVX2機能を有効化するためにこの環境変数が必要になります。</p> <p>CPUの機能は以下のコマンドを使用することで確認できます。</p> <div class="gatsby-highlight" data-language="rust"><pre style="counter-reset: linenumber NaN" class="language-rust line-numbers"><code class="language-rust">rustc <span class="token operator">-</span><span class="token operator">-</span>print<span class="token operator">=</span>cfg <span class="token operator">-</span><span class="token class-name">C</span> target<span class="token operator">-</span>cpu<span class="token operator">=</span>native <span class="token operator">|</span> rg target_feature</code><span aria-hidden="true" class="line-numbers-rows" style="white-space: normal; width: auto; left: 0;"><span></span></span></pre></div> <h3>SIMD</h3> <p>最近傍探索において重要な関数は距離関数であり、この場合はユークリッド距離です。通常は、平方根の計算を避けるためにL2二乗距離を使用します。単純な実装は以下のようになります。</p> <div class="gatsby-highlight" data-language="rust"><pre style="counter-reset: linenumber NaN" class="language-rust line-numbers"><code class="language-rust"><span class="token punctuation">{</span> y<span class="token punctuation">.</span><span class="token function">sub_to</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> <span class="token operator">&</span><span class="token keyword">mut</span> residual<span class="token punctuation">)</span><span class="token punctuation">;</span> residual<span class="token punctuation">.</span><span class="token function">norm_squared</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span></code><span aria-hidden="true" class="line-numbers-rows" style="white-space: normal; width: auto; left: 0;"><span></span><span></span><span></span><span></span></span></pre></div> <p>プロファイリングの後、<code class="language-text">f32::clone()</code>がまだ残っていることに気づきました。<code class="language-text">nalgebra</code>のソースコードを確認してみると、何らかの理由により多数の<code class="language-text">clone</code>がありました。そこで、SIMDを手書きすることにしました。幸い、<a href="https://github.com/nmslib/hnswlib">hnswlib</a>(人気のHNSW実装)がすでに<a href="https://github.com/nmslib/hnswlib/blob/master/hnswlib/space_l2.h">これ</a>を実装しています。</p> <p>これにより、距離の計算において<code class="language-text">f32::clone()</code>がなくなり、SIFTでQPSが<strong>28</strong>%改善します。<a href="https://github.com/kemingy/rabitq/commit/5f82fccf8b39964ef1f66e9927fb126fd6886765">コミット5f82fcc</a>をご覧ください。</p> <p>筆者のCPUはAVX512に対応していないため、AVX2バージョンを使用しています。<a href="https://store.steampowered.com/hwsurvey/">Steamでハードウェアの統計データ</a>を確認できますが、「<em>Other Settings</em>」にSIMDのサポートが記載されています。<em>100</em>%のユーザーがSSE3に対応し、<em>94.61</em>%のユーザーがAVX2に対応していますが、AVX512Fに対応しているユーザーは<em>13.06</em>%に過ぎません。当然この統計データは偏っており、ほとんどのクラウドIntel CPUはAVX512に対応しています。ゲームプレイヤーがすべてのユーザーを代表することはできません。</p> <p>SIMDを使用する上で非常に役立つガイドとして<a href="https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#">Intel Intrinsics Guide</a>が挙げられます。オンラインだと使い勝手が良くないため、サイトをダウンロードすることをおすすめします。組み込み関数の「<strong>レイテンシ</strong>」と「<strong>スループット</strong>」は必ず確認してください。そうしないと、通常のバージョンよりもコードが遅くなる場合があります。</p> <p><a href="https://db.in.tum.de/~finis/x86%20intrinsics%20cheat%20sheet%20v1.0.pdf">x86 Intrinsics Cheat Sheet</a>というリソースもあります。こちらは筆者のような初心者が使いやすい内容になっています。</p> <p><a href="https://github.com/ashvardanian">@ashvardanian</a>が、テール要素問題を解決する「マスクロード」(AVX512が必要)に関する記事を<a href="https://ashvardanian.com/posts/simsimd-faster-scipy/#tails-of-the-past-the-significance-of-masked-loads">投稿</a>しています。</p> <p>コードを他のプラットフォームでも実行できるようにするには、以下を行います。 <code class="language-text">rust #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] { if is_x86_feature_detected!("avx2") { // AVX2 version } else { // normal version } } </code></p> <p>SIMD向けにより良いcfgを書くのに役立つクレートがいくつかありますが、今のところは複雑にせず、シンプルにしておきましょう。</p> <h3>SIMDに関する補足</h3> <p>SIMDは金槌のようなものなので、今度はコードの中の「釘」をもっと見つける必要があります。</p> <p><a href="https://github.com/kemingy/rabitq/commit/f114fc1ec58686596ade0df02a96fcf04b0bf828">コミットf114fc1</a>でAVX2を使用して<code class="language-text">binarize_vector</code>関数を書き換えたところ、GistのQPSが<strong>32</strong>%改善した</p> <p><del>元のC++版に比べて、この実装も分岐がありません</del>。<code class="language-text">opt-level=3</code>を有効化すると、コンパイラによってこれを最適化することができます。<a href="https://godbolt.org/z/hjP5qjabz">アセンブリ</a>をご覧ください。</p> <div class="gatsby-highlight" data-language="diff"><pre style="counter-reset: linenumber NaN" class="language-diff line-numbers"><code class="language-diff">@andrewaylett pointed out that opt-level=3 can optimize this</code><span aria-hidden="true" class="line-numbers-rows" style="white-space: normal; width: auto; left: 0;"><span></span></span></pre></div> <p><em>opt-level=3でこれを最適化できると@andrewaylettが指摘</em></p> <div class="gatsby-highlight" data-language="diff"><pre style="counter-reset: linenumber NaN" class="language-diff line-numbers"><code class="language-diff"><span class="token deleted-sign deleted"><span class="token prefix deleted">-</span> let shift = if (i / 32) % 2 == 0 { 32 } else { 0 }; </span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span> let shift = ((i >> 5) & 1) << 5; // opposite version because I store the binary in u64 with different endian from the C++ version</span></code><span aria-hidden="true" class="line-numbers-rows" style="white-space: normal; width: auto; left: 0;"><span></span><span></span></span></pre></div> <p>-<em>let shift = if (i / 32) % 2 == 0 { 32 } else { 0 };</em></p> <p>+<em>let shift = ((i >> 5) & 1) << 5; // C++版とは異なるエンディアンを使用してバイナリをu64に格納するため、逆バージョン</em></p> <div class="gatsby-highlight" data-language="diff"><pre style="counter-reset: linenumber NaN" class="language-diff line-numbers"><code class="language-diff">@NovaX first pointed out that it's equivalent to i & 32, which is more readable.</code><span aria-hidden="true" class="line-numbers-rows" style="white-space: normal; width: auto; left: 0;"><span></span></span></pre></div> <p><em>より可読性に優れたi & 32と同等であると、@NovaXが最初に指摘</em></p> <h3>スカラー量子化</h3> <p>コード内の<code class="language-text">f32::clone()</code>を減らすため、筆者はもっと多くの<code class="language-text">nalgebra</code>関数を手動で実装することにしました。<code class="language-text">min</code>および<code class="language-text">max</code>関数が最も一般的なものです。<code class="language-text">nalgebra</code>バージョンは以下のようになります。</p> <div class="gatsby-highlight" data-language="rust"><pre style="counter-reset: linenumber NaN" class="language-rust line-numbers"><code class="language-rust"><span class="token keyword">let</span> lower_bound <span class="token operator">=</span> residual<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> upper_bound <span class="token operator">=</span> residual<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code><span aria-hidden="true" class="line-numbers-rows" style="white-space: normal; width: auto; left: 0;"><span></span><span></span></span></pre></div> <p>これは以下により行います。</p> <div class="gatsby-highlight" data-language="rust"><pre style="counter-reset: linenumber NaN" class="language-rust line-numbers"><code class="language-rust"><span class="token keyword">fn</span> <span class="token function-definition function">min_max</span><span class="token punctuation">(</span>vec<span class="token punctuation">:</span> <span class="token operator">&</span><span class="token punctuation">[</span><span class="token keyword">f32</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token punctuation">(</span><span class="token keyword">f32</span><span class="token punctuation">,</span> <span class="token keyword">f32</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> <span class="token keyword">mut</span> min <span class="token operator">=</span> <span class="token keyword">f32</span><span class="token punctuation">::</span><span class="token constant">MAX</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token keyword">mut</span> max <span class="token operator">=</span> <span class="token keyword">f32</span><span class="token punctuation">::</span><span class="token constant">MIN</span><span class="token punctuation">;</span> <span class="token keyword">for</span> v <span class="token keyword">in</span> vec<span class="token punctuation">.</span><span class="token function">iter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token operator">*</span>v <span class="token operator"><</span> min <span class="token punctuation">{</span> min <span class="token operator">=</span> <span class="token operator">*</span>v<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token operator">*</span>v <span class="token operator">></span> max <span class="token punctuation">{</span> max <span class="token operator">=</span> <span class="token operator">*</span>v<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">(</span>min<span class="token punctuation">,</span> max<span class="token punctuation">)</span> <span class="token punctuation">}</span></code><span aria-hidden="true" class="line-numbers-rows" style="white-space: normal; width: auto; left: 0;"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div> <p>以前は便利なので<code class="language-text">f32::min()</code>と<code class="language-text">f32::max()</code>を使用していましたが、昇順/降順以外のベクトルについては<code class="language-text">if</code>の方がパフォーマンスが優れています。</p> <p>次のようにメソッドチェーンでベクトルに対して処理を数回繰り返し実行し、複数のイテレーションでの集計によりスカラー量子化を計算する代わりに、</p> <div class="gatsby-highlight" data-language="rust"><pre style="counter-reset: linenumber NaN" class="language-rust line-numbers"><code class="language-rust"><span class="token keyword">let</span> y_scaled <span class="token operator">=</span> residual<span class="token punctuation">.</span><span class="token function">add_scalar</span><span class="token punctuation">(</span><span class="token operator">-</span>lower_bound<span class="token punctuation">)</span> <span class="token operator">*</span> one_over_delta <span class="token operator">+</span> <span class="token operator">&</span><span class="token keyword">self</span><span class="token punctuation">.</span>rand_bias<span class="token punctuation">;</span> <span class="token keyword">let</span> y_quantized <span class="token operator">=</span> y_scaled<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token closure-params"><span class="token closure-punctuation punctuation">|</span>v<span class="token closure-punctuation punctuation">|</span></span> v<span class="token punctuation">.</span><span class="token function">to_u8</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">expect</span><span class="token punctuation">(</span><span class="token string">"convert to u8 error"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> scalar_sum <span class="token operator">=</span> y_quantized<span class="token punctuation">.</span><span class="token function">iter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">fold</span><span class="token punctuation">(</span><span class="token number">0u32</span><span class="token punctuation">,</span> <span class="token closure-params"><span class="token closure-punctuation punctuation">|</span>acc<span class="token punctuation">,</span> <span class="token operator">&</span>v<span class="token closure-punctuation punctuation">|</span></span> acc <span class="token operator">+</span> v <span class="token keyword">as</span> <span class="token keyword">u32</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code><span aria-hidden="true" class="line-numbers-rows" style="white-space: normal; width: auto; left: 0;"><span></span><span></span><span></span></span></pre></div> <p>1回のループでこれを実行できます。</p> <div class="gatsby-highlight" data-language="rust"><pre style="counter-reset: linenumber NaN" class="language-rust line-numbers"><code class="language-rust"><span class="token punctuation">{</span> <span class="token keyword">let</span> <span class="token keyword">mut</span> sum <span class="token operator">=</span> <span class="token number">0u32</span><span class="token punctuation">;</span> <span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token number">0</span><span class="token punctuation">..</span>vec<span class="token punctuation">.</span><span class="token function">len</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> q <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>vec<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">-</span> lower_bound<span class="token punctuation">)</span> <span class="token operator">*</span> multiplier <span class="token operator">+</span> bias<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token keyword">as</span> <span class="token keyword">u8</span><span class="token punctuation">;</span> quantized<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> q<span class="token punctuation">;</span> sum <span class="token operator">+=</span> q <span class="token keyword">as</span> <span class="token keyword">u32</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> sum <span class="token punctuation">}</span></code><span aria-hidden="true" class="line-numbers-rows" style="white-space: normal; width: auto; left: 0;"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div> <p>スカラー量子化については、<code class="language-text">f32</code>を<code class="language-text">u8</code>に変換できることは分かっているため、<code class="language-text">to_u8().unwrap()</code>の代わりに<code class="language-text">as u8</code>を使用できます。 <a href="https://github.com/kemingy/rabitq/commit/af39c1ce47eb8ea32e11f47b99548e77846397ea">コミットaf39c1c</a>および<a href="https://github.com/kemingy/rabitq/commit/d2d51b0785f0234df4d83a60eea96a36486a1120">コミットd2d51b0</a>は、GistのQPSを<strong>31</strong>%改善しました。 以下の部分もSIMDで書き換えることができ、これによりGistのQPSが12%改善します。</p> <ul> <li>最小/最大:<a href="https://github.com/kemingy/rabitq/commit/c97be68c13c7b4498b564afe3de2a1f6d8bca5ce">コミットc97be68</a>および<a href="https://github.com/kemingy/rabitq/commit/e5a4af05433bf724da6902d34a745b4b2bdefd8d">コミットe5a4af0</a></li> <li>スカラー量子化:<a href="https://github.com/kemingy/rabitq/commit/28efe097a46696bb1a5469db22e500bafdc04514">コミット28efe09</a></li> </ul> <p>tr_mulをベクトル射影であるSIMDに置き換えることも試してみました。ここでは、<code class="language-text">nalgebra</code>がBLASを使用することが判明したため、パフォーマンスは変わりません。</p> <h3>新たな代数クレート:faer</h3> <p><code class="language-text">f32::clone()</code>の問題について調べている際に、<a href="https://github.com/sarah-quinones/faer-rs">faer</a>という新たなRust代数クレートを見つけました。多数のSIMDにより最適化されており、行と列のイテレーションパフォーマンスを向上させます。QR分解もnalgebraよりかなり高速です。こちらの<a href="https://github.com/kemingy/rabitq/commit/04118219d28bd0d43594c98c71e752faa81ff79d">コミット0411821</a>はトレーニング部分を高速化します。</p> <p>また、<a href="https://github.com/kemingy/rabitq/commit/0d969bdcfb331f87e938e043e01acc648e1cf963">コミット0d969bd</a>以降は<code class="language-text">ColRef</code>や<code class="language-text">RowRef</code>ラッパーなしでこれらのベクトルを通常のスライスとして使用できます。</p> <p>最初からfaerを使っていれば、多くのトラブルを回避できていたでしょう。いずれにせよ、この経験から多くを学びました。</p> <h3>バイナリ内積</h3> <p>バイナリ内積についてはpopcntがすでに解決済みと思っていましたが、<a href="https://share.firefox.dev/3Yk3Ok8">FlameGraph</a>によると、<code class="language-text">count_ones()</code>の呼び出しが<code class="language-text">binary_dot_product</code>の実行時間に占める割合は7%にすぎないようです。AVX512には<code class="language-text">vpopcntq</code>命令がありますが、AVX2シミュレーションの方が一般的なので、筆者はこちらを使用しています。</p> <p><a href="https://github.com/komrad36/popcount/blob/master/popcnt.h">こちら</a>はAVX2を用いたpopcnt実装の良い参考になります。<a href="https://github.com/kemingy/rabitq/commit/edabd4a64c5b8ea2637b5332105638edf16afa7c">コミットedabd4a</a>はこれをRustで再実装したもので、GistのQPSを<strong>11</strong>%改善します。この裏技は、ベクトルに256以上の項目がある場合しかうまくいきません。つまり、バイナリ表現に256ビット必要ということです。</p> <h3>インライン</h3> <p><a href="https://doc.rust-lang.org/reference/attributes/codegen.html#the-inline-attribute">#[inline]</a>属性は慎重に使う必要があります。この属性をすべてのSIMD関数に追加することで、GistのQPSが<strong>5</strong>%改善します。</p> <h3>IO</h3> <p>ここで少し背景情報を追加する必要があります。</p> <p>現行の実装は、<a href="https://en.wikipedia.org/wiki/K-means_clustering">k平均法</a>を用いてベクトルのクラスタリングを行い、セントロイドをメモリに格納するIVFアルゴリズムがベースになっています。クエリベクトルは、<code class="language-text">l2_squared_distance(query, centroid)</code>がより小さいクラスタとしか比較されません。</p> <p>探索する最近傍クラスタの数を制御する<code class="language-text">n_probe</code>というパラメータがあります。<code class="language-text">n_probe</code>の値が大きいと再現率は上がりますが、QPSは下がります。</p> <p>RaBitQは、バイナリ内積を使用しておおよその距離を推定します。しきい値よりも小さい場合は元のL2二乗距離と同じランキングにリランキングし、それとともにしきい値を更新します。</p> <p>筆者は以前、n最近傍を選択するだけで並べ替えを行わない<code class="language-text">slice::select_nth_unstable</code>を使用していました。クエリから遠いクラスタを探索するとリランキング率が上がり、L2二乗距離の計算が増えます。選択したn番目のクラスタを並べ替えることで、GistのQPSが<strong>4</strong>%改善しました。</p> <p>別の裏技として、各クラスタのベクトルをセントロイドまでの距離順に並び替える方法もあります。<a href="https://github.com/kemingy/rabitq/commit/ea13ebca46257d7c2e22250fe02a481e7681f0a9">こちらのコミットea13ebc</a>も、GistのQPSを<strong>4</strong>%改善しました。</p> <p>各ベクトルのおおよその距離の推定に使用するメタデータがいくつかあります。</p> <ul> <li>factor_ip: f32</li> <li>factor_ppc: f32</li> <li>error: f32</li> <li>x_c_distance_square: f32</li> </ul> <p>以前、筆者は4つの<code class="language-text">Vec<f32></code>を使用してこれらのメタデータを格納していましたが、計算を行う際にはそれぞれに<code class="language-text">vector[i]</code>が必要なため、IOには適していませんでした。<a href="https://github.com/kemingy/rabitq/commit/bb440e3e8b150f590523eaa77e7c62165a5ee764">コミットbb440e3</a>でこれらを一つのstructに組み合わせることで、GistのQPSが<strong>2.5</strong>%改善しました。これは4xf32であるためうまく行き、そのためC表現を直接使用することができます。</p> <div class="gatsby-highlight" data-language="rust"><pre style="counter-reset: linenumber NaN" class="language-rust line-numbers"><code class="language-rust"><span class="token attribute attr-name">#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]</span> <span class="token attribute attr-name">#[repr(C)]</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">Factor</span> <span class="token punctuation">{</span> factor_ip<span class="token punctuation">:</span> <span class="token keyword">f32</span><span class="token punctuation">,</span> factor_ppc<span class="token punctuation">:</span> <span class="token keyword">f32</span><span class="token punctuation">,</span> error_bound<span class="token punctuation">:</span> <span class="token keyword">f32</span><span class="token punctuation">,</span> center_distance_square<span class="token punctuation">:</span> <span class="token keyword">f32</span><span class="token punctuation">,</span> <span class="token punctuation">}</span></code><span aria-hidden="true" class="line-numbers-rows" style="white-space: normal; width: auto; left: 0;"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div> <p>残念ながら、<code class="language-text">faer</code>はu64ベクトルに対応していません。したがって、ベクトルのバイナリ表現を<code class="language-text">Vec<Vec<u64>></code>に格納する必要があります。<a href="https://github.com/kemingy/rabitq/commit/48236b23069db92bdb741fc6693e126b52c397ce">コミット48236b2</a>でこれを<code class="language-text">Vec<u64></code>に変更することで、GistのQPSが<strong>2</strong>%改善しました。</p> <h3>const generics</h3> <p>C++版は、テンプレートを使用して異なる項目のコードを生成します。この機能はRustにもありますが、異なる項目用のコードの再コンパイルは、少数の固定された項目しかない会社の中など、特定のユースケースでしか行えない可能性があるため、筆者は試してみませんでした。公開ライブラリでは、ユーザーが自ら再コンパイルする必要がないよう、一般解を提供する方が良いでしょう。</p> <h3>その他のツール</h3> <p><a href="https://github.com/Shnatsel/bounds-check-cookbook/">bounds-check-cookbook</a>では、safe Rustで境界チェックを無くす方法の例をいくつか紹介しています。</p> <p>筆者は<a href="https://doc.rust-lang.org/rustc/profile-guided-optimization.html">PGO</a>と<a href="https://github.com/llvm/llvm-project/tree/main/bolt">BOLT</a>を試してみましたが、改善は得られませんでした。</p> <p><a href="https://github.com/tikv/jemallocator">jemalloc</a>や<a href="https://github.com/microsoft/mimalloc">mimalloc</a>に変えてもパフォーマンスは改善しません。</p> <h2>まとめ</h2> <ul> <li>SIMDは適切に使用すれば素晴らしい</li> <li>特に大きなデータセットではIOも重要</li> </ul> <p>データセットGistを使用したパフォーマンスは、現時点ではC++版と同じです。筆者はSIMDをより頻繁に使用しますが、C++版はconst genericsを使用しています。</p> <h2>参考文献</h2> <ul> <li><a href="https://en.algorithmica.org/hpc/algorithms/matmul/">Algorithmica / HPC</a></li> </ul> <p><img src="https://i.creativecommons.org/l/by-nc-sa/4.0/80x15.png" style="width: initial"> <br> この著作物のライセンスは、<a href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>に基づいて付与されています。</p></div><div data-testid="supervisor-info" class="SupervisorInfo__Wrapper-sc-1j48flx-0 flbPUF"><span class="SupervisorInfo__Header-sc-1j48flx-1 dvXvVG">監修者</span><div class="SupervisorInfo__ImageWrapper-sc-1j48flx-2 ftZoJh"><img src="data:image/jpeg;base64,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" alt="監修者_古川陽介" class="SupervisorInfo__Image-sc-1j48flx-3 mBQUt"/></div><div class="SupervisorInfo__NameWrapper-sc-1j48flx-4 eoJhWn"><b data-testid="supervisor-name" class="SupervisorInfo__Name-sc-1j48flx-5 hPxcFm">古川陽介</b><br/>株式会社リクルート プロダクト統括本部 プロダクト開発統括室 グループマネジャー 株式会社ニジボックス デベロップメント室 室長 Node.js 日本ユーザーグループ代表</div><div class="SupervisorInfo__Introduce-sc-1j48flx-6 hHtnWv">複合機メーカー、ゲーム会社を経て、2016年に株式会社リクルートテクノロジーズ(現リクルート)入社。 現在はAPソリューショングループのマネジャーとしてアプリ基盤の改善や運用、各種開発支援ツールの開発、またテックリードとしてエンジニアチームの支援や育成までを担う。 2019年より株式会社ニジボックスを兼務し、室長としてエンジニア育成基盤の設計、技術指南も遂行。 Node.js 日本ユーザーグループの代表を務め、Node学園祭などを主宰。<ul class="SupervisorInfo__SocialLinkWrapper-sc-1j48flx-7 dGIkDp"><li class="SupervisorInfo__SocialLinkItem-sc-1j48flx-8 lfoiSu">Twitter<!-- -->:<!-- --> <a href="https://twitter.com/yosuke_furukawa" title="Twitter" rel="noopener external noreferrer" target="_blank" data-wpel-link="external" class="SupervisorInfo__SocialLink-sc-1j48flx-9 gZbwdw">@yosuke_furukawa</a></li><li class="SupervisorInfo__SocialLinkItem-sc-1j48flx-8 lfoiSu">Github<!-- -->:<!-- --> <a href="https://github.com/yosuke-furukawa" title="Github" rel="noopener external noreferrer" target="_blank" data-wpel-link="external" class="SupervisorInfo__SocialLink-sc-1j48flx-9 gZbwdw">yosuke-furukawa</a></li></ul></div></div><div class="RelatedPostsList__Wrapper-sc-4059vb-0 jhDMNW"><h2 class="RelatedPostsList__Header-sc-4059vb-1 ccjKdX">関連記事</h2><div class="RelatedPostsList__GridWrapper-sc-4059vb-2 XNfFC"><div class="RelatedPostsList__Card-sc-4059vb-3 iVnrAu"><div class="RelatedPostsList__ThumbnailWrapper-sc-4059vb-4 dsGZua"><a href="/a-gpu-approach-to-path-finding/"><img src="/wp/wp-content/uploads/2015/07/dabda1bf7f34fe964c6c82824b6bda03-500x504.png" width="280" height="183" class="ArticleCardThumbnail__Thumbnail-sc-7xjim1-0 fpWdTs"/></a></div><div class="RelatedPostsList__InfoWrapper-sc-4059vb-5 lnIryr"><div class="ArticleCardInfo__Wrapper-sc-c5jz68-0 flEpUP"><p class="ArticleCardDate__Text-sc-1wiuzo7-0 etKuix">2015年7月24日</p><div class="ArticleCardInfo__TitleWrapper-sc-c5jz68-1 mmaeQ"><h3><a class="ArticleCardTitle__Text-sc-1rk0g9j-0 aBiaF" href="/a-gpu-approach-to-path-finding/">GPUとセルオートマトンで経路探索問題を解いてみる</a></h3></div><div class="ArticleCardInfo__DescriptionWrapper-sc-c5jz68-2 biuIkY"></div></div></div><div class="RelatedPostsList__TagsWrapper-sc-4059vb-6 dzSQvE"><ul class="ArticleCardTagsList__List-sc-1wyunq3-0 bHlduO"><li class="ArticleCardTagsList__Item-sc-1wyunq3-1 eGBDcv"><a class="ArticleCardTag__Text-sc-1bp09p2-0 jFjNGd" href="/tag/algorithm/">アルゴリズム</a></li><li class="ArticleCardTagsList__Item-sc-1wyunq3-1 eGBDcv"><a class="ArticleCardTag__Text-sc-1bp09p2-0 jFjNGd" href="/tag/performance/">パフォーマンス</a></li></ul></div></div><div class="RelatedPostsList__Card-sc-4059vb-3 iVnrAu"><div class="RelatedPostsList__ThumbnailWrapper-sc-4059vb-4 dsGZua"><a href="/adventures-in-jit-compilation-part-2-an-x64-jit/"><img src="/wp/wp-content/uploads/2017/09/brainfuck-500x500.png" width="280" height="183" class="ArticleCardThumbnail__Thumbnail-sc-7xjim1-0 fpWdTs"/></a></div><div class="RelatedPostsList__InfoWrapper-sc-4059vb-5 lnIryr"><div class="ArticleCardInfo__Wrapper-sc-c5jz68-0 flEpUP"><p class="ArticleCardDate__Text-sc-1wiuzo7-0 etKuix">2017年9月26日</p><div class="ArticleCardInfo__TitleWrapper-sc-c5jz68-1 mmaeQ"><h3><a class="ArticleCardTitle__Text-sc-1rk0g9j-0 aBiaF" href="/adventures-in-jit-compilation-part-2-an-x64-jit/">JITコンパイル での冒険 パート2:x64 JIT</a></h3></div><div class="ArticleCardInfo__DescriptionWrapper-sc-c5jz68-2 biuIkY"></div></div></div><div class="RelatedPostsList__TagsWrapper-sc-4059vb-6 dzSQvE"><ul class="ArticleCardTagsList__List-sc-1wyunq3-0 bHlduO"><li class="ArticleCardTagsList__Item-sc-1wyunq3-1 eGBDcv"><a class="ArticleCardTag__Text-sc-1bp09p2-0 jFjNGd" href="/tag/algorithm/">アルゴリズム</a></li><li class="ArticleCardTagsList__Item-sc-1wyunq3-1 eGBDcv"><a class="ArticleCardTag__Text-sc-1bp09p2-0 jFjNGd" href="/tag/performance/">パフォーマンス</a></li><li class="ArticleCardTagsList__Item-sc-1wyunq3-1 eGBDcv"><a class="ArticleCardTag__Text-sc-1bp09p2-0 jFjNGd" href="/tag/for-beginners/">入門</a></li></ul></div></div><div class="RelatedPostsList__Card-sc-4059vb-3 iVnrAu"><div class="RelatedPostsList__ThumbnailWrapper-sc-4059vb-4 dsGZua"><a href="/adventures-in-jit-compilation-part-1-an-interpreter/"><img src="/wp/wp-content/uploads/2017/09/brainfuck-500x500.png" width="280" height="183" class="ArticleCardThumbnail__Thumbnail-sc-7xjim1-0 fpWdTs"/></a></div><div class="RelatedPostsList__InfoWrapper-sc-4059vb-5 lnIryr"><div class="ArticleCardInfo__Wrapper-sc-c5jz68-0 flEpUP"><p class="ArticleCardDate__Text-sc-1wiuzo7-0 etKuix">2017年9月12日</p><div class="ArticleCardInfo__TitleWrapper-sc-c5jz68-1 mmaeQ"><h3><a class="ArticleCardTitle__Text-sc-1rk0g9j-0 aBiaF" href="/adventures-in-jit-compilation-part-1-an-interpreter/">JITコンパイルでの冒険 パート1:インタプリタ</a></h3></div><div class="ArticleCardInfo__DescriptionWrapper-sc-c5jz68-2 biuIkY"></div></div></div><div class="RelatedPostsList__TagsWrapper-sc-4059vb-6 dzSQvE"><ul class="ArticleCardTagsList__List-sc-1wyunq3-0 bHlduO"><li class="ArticleCardTagsList__Item-sc-1wyunq3-1 eGBDcv"><a class="ArticleCardTag__Text-sc-1bp09p2-0 jFjNGd" href="/tag/algorithm/">アルゴリズム</a></li><li class="ArticleCardTagsList__Item-sc-1wyunq3-1 eGBDcv"><a class="ArticleCardTag__Text-sc-1bp09p2-0 jFjNGd" href="/tag/performance/">