PageSourceSearch

https://www.parca.dev/docs/assets/js/7a66262a.3b3c4e7e.js

js parca.dev collected 2026-10-03 21:34:27 UTC 7,408 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkparca_dev=globalThis.webpackChunkparca_dev||[]).push([[8552],{5680(e,t,a){a.d(t,{xA:()=>c,yg:()=>d});var n=a(6540);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach(function(t){r(e,t,a[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))})}return e}function l(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var p=n.createContext({}),s=function(e){var t=n.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=s(e.components);return n.createElement(p.Provider,{value:t},e.children)},g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef(function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=s(a),d=r,f=u["".concat(p,".").concat(d)]||u[d]||g[d]||i;return a?n.createElement(f,o(o({ref:t},c),{},{components:a})):n.createElement(f,o({ref:t},c))});function d(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=u;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:r,o[1]=l;for(var s=2;s<i;s++)o[s]=a[s];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}u.displayName="MDXCreateElement"},7397(e,t,a){a.r(t),a.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>g,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var n=a(8168),r=(a(6540),a(5680));const i={},o="CPU Profiling",l={unversionedId:"profiling-101",id:"profiling-101",title:"CPU Profiling",description:"Understand basics of CPU profiling in 5 minutes \u23f1\ufe0f!",source:"@site/docs/profiling-101.md",sourceDirName:".",slug:"/profiling-101",permalink:"/docs/profiling-101",draft:!1,editUrl:"https://github.com/parca-dev/parca.dev/edit/main/docs/profiling-101.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Public Exposing Parca Write Endpoints",permalink:"/docs/exposing-parca-write"},next:{title:"Instrument your Go app with pprof",permalink:"/docs/instrumenting-go"}},p={},s=[{value:"Example",id:"example",level:2},{value:"Capturing data",id:"capturing-data",level:3},{value:"Data format",id:"data-format",level:3},{value:"Visualizing",id:"visualizing",level:3},{value:"Recap",id:"recap",level:2}],c={toc:s};function g({components:e,...t}){return(0,r.yg)("wrapper",(0,n.A)({},c,t,{components:e,mdxType:"MDXLayout"}),(0,r.yg)("h1",{id:"cpu-profiling"},"CPU Profiling"),(0,r.yg)("p",null,"Understand basics of CPU profiling in ",(0,r.yg)("strong",{parentName:"p"},"5 minutes")," \u23f1\ufe0f!"),(0,r.yg)("h2",{id:"example"},"Example"),(0,r.yg)("p",null,"This guide will demonstrate CPU profiling using ",(0,r.yg)("a",{parentName:"p",href:"https://golang.org/"},(0,r.yg)("inlineCode",{parentName:"a"},"go")),", but these fundamentals apply to any language. Let's walk through an example of CPU profiling."),(0,r.yg)("h3",{id:"capturing-data"},"Capturing data"),(0,r.yg)("p",null,"Take the following example of a ",(0,r.yg)("a",{parentName:"p",href:"https://golang.org/"},"go")," program that has a ",(0,r.yg)("inlineCode",{parentName:"p"},"main")," function, that first calls ",(0,r.yg)("inlineCode",{parentName:"p"},"iterateLong")," which calls ",(0,r.yg)("inlineCode",{parentName:"p"},"iterate")," with 9 billion iterations, and then ",(0,r.yg)("inlineCode",{parentName:"p"},"iterateShort"),", which calls ",(0,r.yg)("inlineCode",{parentName:"p"},"iterate")," with 1 billion iterations."),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-go"},"package main\n\nfunc main() {\n    iterateLong()\n    iterateShort()\n}\n\nfunc iterateLong() {\n    iterate(9_000_000_000)\n}\n\nfunc iterateShort() {\n    iterate(1_000_000_000)\n}\n\nfunc iterate(iterations int) {\n    for i := 0; i < iterations; i++ {\n    }\n}\n")),(0,r.yg)("p",null,"When executed this program takes 5 seconds to execute in total (on an AMD Ryzen 5 3400GE CPU). With profiling we can understand ",(0,r.yg)("em",{parentName:"p"}
1,"what"),' was executing during those 5 seconds and for how long. For the sake of simplicity, a sampling CPU profiler looks at the "current" stack trace 100x per second (the sampling rate is typically configurable, but 100x is both common and easier to calculate with).'),(0,r.yg)("h3",{id:"data-format"},"Data format"),(0,r.yg)("p",null,"With a profiler running during the execution of the above program it records a profile, that produces the following data in folded stack trace format:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-txt"},"main;iterateLong;iterate 450\nmain;iterateShort;iterate 50\n")),(0,r.yg)("blockquote",null,(0,r.yg)("p",{parentName:"blockquote"},"Parca uses the open standard ",(0,r.yg)("a",{parentName:"p",href:"https://github.com/google/pprof"},(0,r.yg)("inlineCode",{parentName:"a"},"pprof")),", which is optimized to use as little space as possible, but folded stack traces are great for human readability.")),(0,r.yg)("p",null,"10% (50 samples observed out of 500) of the time was spent in the ",(0,r.yg)("inlineCode",{parentName:"p"},"iterate")," function called by ",(0,r.yg)("inlineCode",{parentName:"p"},"iterateShort")," and 90% (450 samples observed out of 500) of the time was spent in the ",(0,r.yg)("inlineCode",{parentName:"p"},"iterate")," function called by ",(0,r.yg)("inlineCode",{parentName:"p"},"iterateLong"),"."),(0,r.yg)("h3",{id:"visualizing"},"Visualizing"),(0,r.yg)("p",null,"Using this data, a popular way to visualize profiling data is using Flame Graphs, or as they are called when they are built from the top being the root, Icicle Graphs."),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"Profiling 101 Flame Graph",src:a(3278).A,width:"1476",height:"172"})),(0,r.yg)("h2",{id:"recap"},"Recap"),(0,r.yg)("p",null,"In this guide you have learned the basic fundamentals of CPU profiling:"),(0,r.yg)("ol",null,(0,r.yg)("li",{parentName:"ol"},"How data is captured: by observing the executed stack traces 100x per second."),(0,r.yg)("li",{parentName:"ol"},"What the raw data looks like: folded stack traces, and the optimized ",(0,r.yg)("a",{parentName:"li",href:"https://github.com/google/pprof"},"pprof")," format."),(0,r.yg)("li",{parentName:"ol"},"Useful ways to visualize data: Flamegraphs/Icicle-Graphs.")),(0,r.yg)("p",null,"Congrats! \ud83c\udf89"))}g.isMDXComponent=!0},3278(e,t,a){a.d(t,{A:()=>n});const n=a.p+"assets/images/profiling-101-icicle-graph-afc1080ce831f406871122cf4c6b796c.png"}}]);

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.