PageSourceSearch

https://getbruin.com/_nuxt/DCbE9YPv.js

js getbruin.com collected 2026-10-03 22:04:48 UTC 16,510 bytes, 2 lines download raw bytes

1import{b as A}from"./D1PsD1RV.js";import{_ as G,o as n,g as r,h as e,t as g,F as k,r as w,n as S,H as U,m as z,q as D,j as st,p as L,e as rt,b as at,i as it,f as O,c as tt,z as lt}from"./1BEqaQKX.js";const ct={class:"ibc"},ut={class:"ibc-head"},dt={class:"ibc-title"},mt={class:"ibc-plot"},pt={class:"ibc-name"},ht={class:"ibc-track"},gt={class:"ibc-secs"},bt={key:0,class:"ibc-mult"},xt=62,ft={__name:"IngestrBenchmarkChart",props:{route:{type:Object,required:!0}},setup(R){const y=R;function f(u){return Number.isFinite(u)?u>=1e3?`${u.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2})}s`:u>=100?`${u.toFixed(1)}s`:`${u.toFixed(2)}s`:"n/a"}const $=D(()=>{const u=y.route.results||[],d=Math.max(...u.map(l=>l.mean),0);return u.map(l=>({command:l.command,label:l.label,highlight:l.highlight,isFastest:l.ratio<=1.005,secs:f(l.mean),mult:l.ratio.toFixed(1),width:d>0?l.mean/d*xt:0}))});return(u,d)=>(n(),r("article",ct,[e("header",ut,[e("h3",dt,g(R.route.label),1)]),e("div",mt,[(n(!0),r(k,null,w($.value,l=>(n(),r("div",{key:l.command,class:S(["ibc-row",{"is-bruin":l.highlight}])},[e("div",pt,g(l.label),1),e("div",ht,[e("div",{class:"ibc-bar",style:U({width:l.width+"%"})},null,4),e("div",{class:"ibc-value",style:U({left:l.width+"%"})},[e("span",gt,g(l.secs),1),l.isFastest?z("",!0):(n(),r("span",bt,g(l.mult)+"×",1))],4)])],2))),128))])]))}},yt=G(ft,[["__scopeId","data-v-14b46d4a"]]),vt={class:"idc"},_t={class:"idc-head"},kt={class:"idc-sub"},wt={class:"idc-tools"},$t={class:"idc-legend"},Ct={class:"idc-seg"},St={class:"idc-plot-wrap"},Mt=["viewBox"],Ft=["x1","y1","x2","y2"],Tt=["x1","y1","x2","y2"],Dt=["x","y"],Bt=["x1","y1","x2","y2"],Lt=["x","y"],Rt=["x1","y1","x2","y2"],Nt=["points","stroke","stroke-width","opacity"],At=["cx","cy","r","fill","opacity"],It=["cx","cy","fill"],jt={class:"idc-tip-head"},Ht={class:"idc-tip-name"},Vt={class:"idc-tip-mult"},Ot={class:"idc-tip-val"},X=1180,et=380,Ut={__name:"IngestrDurationChart",props:{data:{type:Object,required:!0}},setup(R){const y=R,f=L("log"),$=L(null),u=L(null),d={left:70,right:28,top:18,bottom:44},l=X-d.left-d.right,c=et-d.top-d.bottom,p={gong:"#ff5569",ingestr:"#3f4d72",sling:"#c69238",dlt:"#3a8fd0",airbyte:"#8b6fc4",spark:"#2f4858"},m=new Intl.NumberFormat("en-US");function h(s){return s>=1e6?`${s/1e6}M`:s>=1e3?`${s/1e3}K`:String(s)}function b(s){const o=[...s].sort((x,M)=>x-M),t=o.length;if(!t)return 0;const i=Math.floor(t/2);return t%2?o[i]:(o[i-1]+o[i])/2}function v(s,o=5){if(!(s>0))return{max:1,ticks:[0,1]};const t=s/o,i=10**Math.floor(Math.log10(t)),x=t/i,M=(x<1.5?1:x<3?2:x<7?5:10)*i,N=Math.ceil(s/M)*M,j=[];for(let H=0;H<=N+M/1e3;H+=M)j.push(Math.round(H));return{max:N,ticks:j}}const C=D(()=>{const s=new Map;for(const o of y.data.groups)for(const t of o.routes)for(const i of t.results){s.has(i.command)||s.set(i.command,new Map);const x=s.get(i.command);x.has(o.rows)||x.set(o.rows,[]),x.get(o.rows).push(i.mean)}return y.data.tools.filter(o=>s.has(o.command)).map(o=>({command:o.command,label:o.label,highlight:o.highlight,color:p[o.command]||"#64748b",points:[...s.get(o.command).entries()].map(([t,i])=>({rows:t,duration:b(i)})).sort((t,i)=>t.rows-i.rows)}))}),_=D(()=>{const s=C.value,o=s.flatMap(a=>a.points.map(T=>T.duration)).filter(a=>a>0),t=[...new Set(s.flatMap(a=>a.points.map(T=>T.rows)))].sort((a,T)=>a-T);if(!o.length||t.length<2)return{series:s.map(a=>({...a,points:[]})),xTicks:[],yTicks:[]};const i=f.value==="log",x=Math.log10,M=i?x:a=>a,N=Math.min(...o),j=Math.max(...o),H=t,Y=t.length,ot=new Map(t.map((a,T)=>[a,T])),K=l*.04,J=l-K*2,Q=a=>d.left+K+(Y<=1?J/2:ot.get(a)/(Y-1)*J);let V,P,W;if(i){V=x(N)-.15,P=x(j)+.15,W=[];for(let a=Math.ceil(V);a<=Math.floor(P);a+=1)W.push(10**a)}else{const a=v(j);V=0,P=a.max,W=a.ticks}const Z=a=>d.top+c-(M(a)-V)/(P-V)*c,nt=a=>a>=1?`${m.format(a)}s`:`${a}s`;return{series:s.map(a=>({...a,points:a.points.map(T=>({rows:T.rows,x:+Q(T.rows).toFixed(1),y:+Z(T.duration).toFixed(1)}))})),xTicks:H.map(a=>({v:a,x:+Q(a).toFixed(1),label:h(a)})),yTicks:W.map(a=>({v:a,y:+Z(a).toFixed(1),label:nt(a)}))}});function B(s){return Number.isFinite(s)?s>
1=1e3?`${s.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2})}s`:s>=100?`${s.toFixed(1)}s`:`${s.toFixed(2)}s`:"n/a"}function I(s){const o=$.value,t=_.value.xTicks;if(!o||!t.length)return;const i=o.getBoundingClientRect(),x=(s.clientX-i.left)/i.width*X;let M=t[0];for(const N of t)Math.abs(N.x-x)<Math.abs(M.x-x)&&(M=N);u.value=M.v}const F=D(()=>{if(u.value==null)return null;const s=_.value.xTicks.find(t=>t.v===u.value);if(!s)return null;const o=s.x/X*100;return{x:s.x,label:s.label,pct:o,flip:o>58}}),q=D(()=>{if(u.value==null)return[];const s=C.value.map(t=>{const i=t.points.find(x=>x.rows===u.value);return i?{command:t.command,label:t.label,color:t.color,highlight:t.highlight,duration:i.duration}:null}).filter(Boolean).sort((t,i)=>t.duration-i.duration),o=s.length?s[0].duration:0;return s.map(t=>{const i=o>0?t.duration/o:1;return{...t,value:B(t.duration),mult:i<=1.005?null:`${i.toFixed(1)}×`}})}),E=D(()=>{if(u.value==null)return[];const s=[];for(const o of _.value.series){const t=o.points.find(i=>i.rows===u.value);t&&s.push({command:o.command,color:o.color,y:t.y})}return s});return(s,o)=>(n(),r("div",vt,[e("div",_t,[e("div",null,[o[3]||(o[3]=e("h2",{class:"idc-title"},"Duration vs. rows",-1)),e("p",kt,"Median time per tool across data sizes — "+g(f.value)+" duration scale, lower is faster.",1)]),e("div",wt,[e("div",$t,[(n(!0),r(k,null,w(_.value.series,t=>(n(),r("span",{key:t.command},[e("i",{style:U({background:t.color})},null,4),st(g(t.label),1)]))),128))]),e("div",Ct,[e("button",{type:"button",class:S({on:f.value==="log"}),onClick:o[0]||(o[0]=t=>f.value="log")},"Log",2),e("button",{type:"button",class:S({on:f.value==="linear"}),onClick:o[1]||(o[1]=t=>f.value="linear")},"Linear",2)])])]),e("div",St,[(n(),r("svg",{ref_key:"svgRef",ref:$,viewBox:`0 0 ${X} ${et}`,class:"idc-svg",role:"img","aria-label":"Duration versus number of rows, one line per tool",onPointermove:I,onPointerleave:o[2]||(o[2]=t=>u.value=null)},[e("line",{x1:d.left,y1:d.top,x2:d.left,y2:d.top+c,class:"idc-axis"},null,8,Ft),(n(!0),r(k,null,w(_.value.xTicks,t=>(n(),r("g",{key:"x"+t.v},[e("line",{x1:t.x,y1:d.top,x2:t.x,y2:d.top+c,class:"idc-grid"},null,8,Tt),e("text",{x:t.x,y:d.top+c+24,"text-anchor":"middle",class:"idc-tick"},g(t.label),9,Dt)]))),128)),(n(!0),r(k,null,w(_.value.yTicks,t=>(n(),r("g",{key:"y"+t.v},[e("line",{x1:d.left,y1:t.y,x2:d.left+l,y2:t.y,class:"idc-grid"},null,8,Bt),e("text",{x:d.left-12,y:t.y+5,"text-anchor":"end",class:"idc-tick"},g(t.label),9,Lt)]))),128)),F.value?(n(),r("line",{key:0,x1:F.value.x,y1:d.top,x2:F.value.x,y2:d.top+c,class:"idc-cross"},null,8,Rt)):z("",!0),(n(!0),r(k,null,w(_.value.series,t=>(n(),r("g",{key:t.command},[e("polyline",{points:t.points.map(i=>`${i.x},${i.y}`).join(" "),fill:"none",stroke:t.color,"stroke-width":t.highlight?3:2,"stroke-linejoin":"round","stroke-linecap":"round",opacity:1},null,8,Nt),(n(!0),r(k,null,w(t.points,(i,x)=>(n(),r("circle",{key:x,cx:i.x,cy:i.y,r:t.highlight?4.5:3.5,fill:t.color,opacity:1},null,8,At))),128))]))),128)),(n(!0),r(k,null,w(E.value,t=>(n(),r("circle",{key:"mk"+t.command,cx:F.value.x,cy:t.y,r:"5.5",fill:t.color,stroke:"#fff","stroke-width":"2"},null,8,It))),128))],40,Mt)),F.value&&q.value.length?(n(),r("div",{key:0,class:S(["idc-tip",{flip:F.value.flip}]),style:U({left:F.value.pct+"%"})},[e("div",jt,g(F.value.label)+" rows",1),(n(!0),r(k,null,w(q.value,t=>(n(),r("div",{key:t.command,class:S(["idc-tip-row",{on:t.highlight}])},[e("span",{class:"idc-tip-dot",style:U({background:t.color})},null,4),e("span",Ht,g(t.label),1),e("span",Vt,g(t.mult),1),e("span",Ot,g(t.value),1)],2))),128))],6)):z("",!0)])]))}},zt=G(Ut,[["__scopeId","data-v-46458e18"]]),qt={class:"ibt"},Et={class:"ibt-bar"},Pt={class:"ibt-scroll"},Wt={class:"ibt-table"},Xt={class:"ibt-td ibt-left ibt-dim"},Gt={class:"ibt-td ibt-left"},Yt={class:"ibt-td ibt-left"},Kt={__name:"IngestrBenchmarkTable",props:{groups:{type:Array,required:!0},tools:{type:Array,required:!0}},setup(R){const y=R;function f(m){return Number.isFinite(m)?m>=1e3?m.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2}):m>=100?m.toFixed(1):m.toFixed(2):"n/a"}
1function $(m){const[h,b]=m.split("→").map(v=>v.trim());return{source:h||m,dest:b||""}}const u=D(()=>y.tools.filter(m=>y.groups.some(h=>h.routes.some(b=>b.results.some(v=>v.command===m.command))))),d=D(()=>y.groups.flatMap(m=>m.routes.map(h=>{const{source:b,dest:v}=$(h.label),C=Math.min(...h.results.map(_=>_.mean));return{key:`${m.rows}|${h.route}`,rowsLabel:m.rowsLabel,source:b,dest:v,cells:u.value.map(_=>{const B=h.results.find(I=>I.command===_.command);return{command:_.command,highlight:_.highlight,text:B?f(B.mean):"—",fastest:B?B.mean===C:!1}})}}))),l=L(!1);function c(m){const h=String(m);return/[",\n]/.test(h)?`"${h.replace(/"/g,'""')}"`:h}function p(){const h=[["Rows","Source","Destination",...u.value.map(C=>C.label)].map(c).join(",")];for(const C of y.groups)for(const _ of C.routes){const{source:B,dest:I}=$(_.label),F=[C.rowsLabel,B,I];for(const q of u.value){const E=_.results.find(s=>s.command===q.command);F.push(E?E.mean.toFixed(4):"")}h.push(F.map(c).join(","))}const b=h.join(`
2`),v=()=>{l.value=!0,setTimeout(()=>l.value=!1,1500)};if(navigator.clipboard?.writeText)navigator.clipboard.writeText(b).then(v).catch(v);else{const C=document.createElement("textarea");C.value=b,document.body.appendChild(C),C.select(),document.execCommand("copy"),document.body.removeChild(C),v()}}return(m,h)=>(n(),r("div",qt,[e("div",Et,[h[0]||(h[0]=e("span",{class:"ibt-cap"},"All results · seconds per tool, lower is faster",-1)),e("button",{type:"button",class:"ibt-copy",onClick:p},g(l.value?"Copied":"Copy CSV"),1)]),e("div",Pt,[e("table",Wt,[e("thead",null,[e("tr",null,[h[1]||(h[1]=e("th",{class:"ibt-th ibt-left"},"Rows",-1)),h[2]||(h[2]=e("th",{class:"ibt-th ibt-left"},"Source",-1)),h[3]||(h[3]=e("th",{class:"ibt-th ibt-left"},"Destination",-1)),(n(!0),r(k,null,w(u.value,b=>(n(),r("th",{key:b.command,class:S(["ibt-th ibt-num",{"ibt-bruin":b.highlight}])},g(b.label),3))),128))])]),e("tbody",null,[(n(!0),r(k,null,w(d.value,b=>(n(),r("tr",{key:b.key},[e("td",Xt,g(b.rowsLabel),1),e("td",Gt,g(b.source),1),e("td",Yt,g(b.dest),1),(n(!0),r(k,null,w(b.cells,v=>(n(),r("td",{key:v.command,class:S(["ibt-td ibt-num",{"ibt-fastest":v.fastest,"ibt-bruin":v.highlight}])},g(v.text),3))),128))]))),128))])])])]))}},Jt=G(Kt,[["__scopeId","data-v-5501929a"]]),Qt={class:"relative bg-white","data-no-reveal":""},Zt={class:"mx-auto max-w-7xl px-6 pb-4 sm:px-8"},te={class:"sticky top-0 z-10 border-b border-gray-100 bg-white/90 backdrop-blur"},ee={class:"mx-auto flex max-w-7xl flex-wrap items-center gap-x-5 gap-y-2 px-6 py-3 sm:px-8"},se={class:"flex items-center gap-1.5"},oe={class:"flex gap-0.5 rounded border border-gray-200 bg-gray-50 p-0.5"},ne=["onClick"],re={class:"flex items-center gap-1.5"},ae={class:"flex gap-0.5 rounded border border-gray-200 bg-gray-50 p-0.5"},ie=["onClick"],le={class:"flex items-center gap-1.5"},ce={class:"flex gap-0.5 rounded border border-gray-200 bg-gray-50 p-0.5"},ue=["onClick"],de={class:"mx-auto max-w-7xl px-6 py-10 sm:px-8 sm:py-14"},me={class:"mb-5 border-b border-gray-100 pb-2"},pe={class:"text-2xl font-light text-gray-900"},he={class:"grid gap-4 md:grid-cols-2"},ge={key:1,class:"py-16 text-center text-gray-400"},fe={__name:"ingestr",setup(R){const y=L("all"),f=L("all"),$=L("all"),u=L(!1),d=D(()=>A.groups.filter(l=>y.value==="all"||l.rows===y.value).map(l=>({...l,routes:l.routes.filter(c=>(f.value==="all"||c.source===f.value)&&($.value==="all"||c.dest===$.value))})).filter(l=>l.routes.length>0));return rt({title:"ingestr Benchmarks | Bruin",description:"Head-to-head data movement benchmarks: ingestr vs. Sling, dlt, Airbyte, and Spark across sources, destinations, and row counts. ingestr is the fastest in nearly every test.",ogTitle:"ingestr Benchmarks — ingestr vs. Sling, dlt, Airbyte & Spark",ogDescription:"Reproducible data movement benchmarks across sources, destinations, and row counts. Lower is faster.",ogUrl:"https://getbruin.com/benchmarks/ingestr/",ogType:"website",twitterCard:"summary_large_image",twitterTitle:"ingestr Benchmarks",twitterDescription:"ingestr vs. Sling, dlt, Airbyte & Spark — reproducible data movement benchmarks.",robots:"index, follow"}),at({link:[{rel:"canonical",href:"https://getbruin.com/benchmarks/ingestr/"}]}),(l,c)=>(n(),r("main",Qt,[c[8]||(c[8]=e("section",{class:"mx-auto max-w-7xl px-6 pt-16 pb-6 sm:px-8"},[e("h1",{class:"text-3xl font-light text-gray-900 sm:text-4xl"},"ingestr benchmark results")],-1)),e("section",Zt,[it(zt,{data:O(A)},null,8,["data"])]),e("section",te,[e("div",ee,[e("div",se,[c[4]||(c[4]=e("span",{class:"text-[11px] uppercase tracking-wide text-gray-400"},"Rows",-1)),e("div",oe,[e("button",{type:"button",class:S(["rounded px-2 py-1 text-xs",y.value==="all"?"bg-gray-900 text-white":"text-gray-600 hover:bg-white"]),onClick:c[0]||(c[0]=p=>y.value="all")}," All ",2),(n(!0),r(k,null,w(O(A).rowCounts,p=>(n(),r("button",{key:p.rows,type:"button",class:S(["rounded px-2 py-1 text-xs",y.value===p.rows?"bg-gray-900 text-white":"text-gray-600 hover:bg-white"]),onClick:m=>y.value=p.rows},g(p.label),11,ne))),128))])]),e("div",re,[c[5]||(c[5]=e("span",{class:"text-[11px] uppercase tracking-wide text-gray-400"},"Source",-1)),e("div",ae,[e("button",{type:"button",class:S(["rounded px-2 py-1 text-xs",f.value==="all"?"bg-gray-900 text-white":"text-gray-600 hover:bg-white"]),onClick:c[1]||(c[1]=p=>f.value="all")}," All ",2),(n(!0),r(k,null,w(O(A).sources,p=>(n(),r("button",{key:p.id,type:"button",class:S(["rounded px-2 py-1 text-xs",f.value===p.id?"bg-gray-900 text-white":"text-gray-600 hover:bg-white"]),onClick:m=>f.value=p.id},g(p.label),11,ie))),128))])]),e("div",le,[c[6]||(c[6]=e("span",{class:"text-[11px] uppercase tracking-wide text-gray-400"},"Dest",-1)),e("div",ce,[e("button",{type:"button",class:S(["rounded px-2 py-1 text-xs",$.value==="all"?"bg-gray-900 text-white":"text-gray-600 hover:bg-white"]),onClick:c[2]||(c[2]=p=>$.value="all")}," All ",2),(n(!0),r(k,null,w(O(A).destinations,p=>(n(),r("button",{key:p.id,type:"button",class:S(["rounded px-2 py-1 text-xs",$.value===p.id?"bg-gray-900 text-white":"text-gray-600 hover:bg-white"]),onClick:m=>$.value=p.id},g(p.label),11,ue))),128))])]),e("button",{type:"button",class:"ml-auto hidden items-center rounded border border-gray-200 px-2.5 py-1 text-xs text-gray-500 hover:bg-gray-50 hover:text-gray-700 sm:inline-flex",onClick:c[3]||(c[3]=p=>u.value=!u.value)},g(u.value?"Hide table":"View as table"),1)])]),e("section",de,[u.value?(n(),tt(Jt,{key:0,groups:d.value,tools:O(A).tools,class:"mb-12 hidden sm:block"},null,8,["groups","tools"])):z("",!0),(n(!0),r(k,null,w(d.value,p=>(n(),r("div",{key:p.rows,class:"mb-12 last:mb-0"},[e("div",me,[e("h2",pe,[st(g(p.rowsLabel)+" ",1),c[7]||(c[7]=e("span",{class:"text-gray-400"},"rows",-1))])]),e("div",he,[(n(!0),r(k,null,w(p.routes,m=>(n(),tt(yt,{key:m.route,route:m},null,8,["route"]))),128))])]))),128)),d.value.length===0?(n(),r("p",ge," No benchmarks for this selection. ")):z("",!0)]),c[9]||(c[9]=lt('<section class="border-t border-gray-100 bg-gray-50"><div class="mx-auto max-w-3xl px-6 py-12 sm:px-8"><h2 class="text-sm uppercase tracking-wide text-gray-500">Methodology</h2><div class="mt-4 space-y-3 text-sm leading-6 text-gray-600"><p> Each tool runs the same source-to-destination copy for a fixed number of rows. Times are wall-clock, measured with <a href="https://github.com/sharkdp/hyperfine" target="_blank" rel="noopener" class="text-bruin-400 underline">hyperfine</a>, with a warmup run discarded and the mean of the timed runs reported. The multiplier shows how many times slower a tool is than the fastest one in that chart. </p><p>
2 All tools were run on the same machine with identical source data and warehouse targets. Numbers are reproducible from the raw benchmark dumps — see the <a href="https://github.com/bruin-data/ingestr/tree/main/benchmarks" target="_blank" rel="noopener" class="text-bruin-400 underline">benchmark code</a>. Runs are refreshed as engines change — the most recent run wins for each source / destination / row-count combination. </p><p> Benchmarks were executed on a Hetzner Cloud CCX63 instance (48 dedicated AMD EPYC-Milan vCPUs, 192 GB RAM, NVMe SSD), running Ubuntu 24.04.4 LTS. </p></div></div></section>',1))]))}};export{fe as default};

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