<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>israelo.io</title>
        <description>I write about eBPF, containers, Kubernetes, and OTel, and journal my daughter Naomi&apos;s coding journey here, a nine-year-old with a budding passion for programming. When I&apos;m not working, you&apos;ll find me teaching my girls how to code, embarking on long bike trips that sometimes turn into hikes in good weather, playing chess, or enjoying meals and drinks with friends.</description>
        <link>https://israelo.io/</link>
        <atom:link href="https://israelo.io/feed.xml" rel="self" type="application/rss+xml"/>
        <pubDate>Mon, 16 Mar 2026 12:43:01 +0000</pubDate>
        <lastBuildDate>Mon, 16 Mar 2026 12:43:01 +0000</lastBuildDate>
        <generator>Jekyll v3.10.0</generator>
        
            <item>
                <title>Coming for Cancer with Quantum-Accelerated Pipelines</title>
                <description>&lt;h2 id=&quot;coming-for-cancer-with-quantum-power&quot;&gt;Coming for Cancer With Quantum Power&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;An excerpt from my diary.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is my next mission, the thing I’m building toward, not just funding research or writing cheques but actually building the infrastructure, the partnerships, and the quantum-accelerated pipelines that will make cancer &lt;ins&gt;was&lt;/ins&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cancer took too much from me already. I’m not waiting for it to take more.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;My next big mission is to make cancer &lt;ins&gt;was&lt;/ins&gt;.  The way smallpox &lt;ins&gt;was&lt;/ins&gt; a global killer. The way polio &lt;ins&gt;was&lt;/ins&gt; a childhood terror. Cancer will be something our grandchildren read about in history books, not something they watch destroy their families.&lt;/p&gt;

&lt;p&gt;“Cancer &lt;ins&gt;was&lt;/ins&gt; a terrible disease” –&amp;gt; makes a great PR-FAQ.&lt;/p&gt;

&lt;p&gt;__&lt;/p&gt;

&lt;p&gt;Cancer killed my grandmother. It killed my mum. My sister fought it and won, but she lost a part of herself in the process. Thank God she’d finished having kids by then.&lt;/p&gt;

&lt;p&gt;This is personal. I have two daughters. Cancer came for three generations of women in my family. My daughters won’t be next.&lt;/p&gt;

&lt;p&gt;So I’m coming for it first, with everything I’ve got.&lt;/p&gt;

&lt;p&gt;You don’t feel the pain and urgency until it happens to you. It kills slow. It leaves flashbacks that wake you up in the middle of the night with tears running down your cheeks.&lt;/p&gt;

&lt;p&gt;I believe the current paradigms around cancer research, diagnostics, and treatment are too politicized and too incremental. If you think otherwise, I respect it, but you don’t feel the urgency if it hasn’t quietly dismantled your world. The world needs urgency, boldness, and radical clarity. And that urgency has to be channeled through advanced technology, especially the rising frontier of &lt;strong&gt;quantum computing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Quantum computing offers a chance to reimagine what’s possible: simulating molecular and cellular dynamics at speeds and scales we’ve never had before; detecting cancer earlier; designing smarter therapies; personalizing treatments in ways old systems can’t approach. Researchers have already used quantum-classical models to design molecules targeting proteins once considered “undruggable.”[1] Quantum computers have solved problems in minutes that would take classical supercomputers thousands of years.[2]&lt;/p&gt;

&lt;p&gt;The infrastructure is emerging. Research institutions and technology companies around the world are proving what can be done. But we need more. We need speed. We need people who won’t settle for incremental progress while people die waiting.&lt;/p&gt;

&lt;p&gt;I’m coming for it. I believe we can use technology to make cancer &lt;ins&gt;was&lt;/ins&gt;. This is my life’s mission. The results may come long after I’m gone, but I have to fight.&lt;/p&gt;

&lt;p&gt;If you’ve got tips, or want to join me in forming an interest group, let’s connect.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;p&gt;[1] Aspuru-Guzik, A. et al. (2025). “AI and quantum computing used to target ‘undruggable’ cancer protein.” &lt;em&gt;University of Toronto Faculty of Arts &amp;amp; Science&lt;/em&gt;. https://www.artsci.utoronto.ca/news/ai-and-quantum-computing-used-target-undruggable-cancer-protein&lt;/p&gt;

&lt;p&gt;[2] “Quantum Computing Cancer Research: Transforming Healthcare.” (2024). &lt;em&gt;Infiniti Research&lt;/em&gt;. https://www.infinitiresearch.com/thoughts/quantum-computing-in-cancer-research-a-new-era-of-drug-discovery-and-treatment/&lt;/p&gt;
</description>
                <pubDate>Thu, 27 Nov 2025 03:01:35 +0000</pubDate>
                <link>https://israelo.io/blog/coming-for-cancer/</link>
                <guid isPermaLink="true">https://israelo.io/blog/coming-for-cancer/</guid>
                
                <category>mum</category>
                
                <category>life</category>
                
                
                <category>personal</category>
                
            </item>
        
            <item>
                <title>The Hidden Curse of Love</title>
                <description>&lt;p&gt;Love feels natural, effortless, and beautiful. Yet hidden within it is a curse that only reveals itself when you lose someone you love deeply.&lt;/p&gt;

&lt;p&gt;Put another way, buried deep within love is something we rarely talk about — its hidden cost. The harder you love, the deeper the pain of loss.&lt;/p&gt;

&lt;p&gt;I’ve been thinking a lot about my mum. I loved her deeply.  I went back to her home in Nigeria this September, the first time since we lost her. It took days before I could walk into her room. Every corner of that house carried her presence. Her voice. Her scent. Her peace. I could almost hear her call my name. It was rough.&lt;/p&gt;

&lt;p&gt;I kept asking why the pain felt heavier than the memories. Why grief seemed to drown the love we had. I needed to process this some more, so I pulled out a pen and paper.&lt;/p&gt;

&lt;p&gt;A realization occurred. The hardest part wasn’t just losing her. It was her final five months. &lt;strong&gt;Cancer is a bastard&lt;/strong&gt;. It strips away strength and light, leaving only pain. Watching her fade and groan in agony broke something inside me. It replaced my belief in a kind universe with the cold reality of its indifference.&lt;/p&gt;

&lt;p&gt;Since then, I’ve been reflecting on love’s complexity. It feels so beautiful and natural when it flows, but it a heavy burden that only reveals itself in loss. Grief can feel heavier than memory, louder than joy. It threatens to overshadow everything that once made love feel safe.&lt;/p&gt;

&lt;p&gt;Maybe that’s the truth of it. The same love that brings immense joy also creates a deep void when it’s gone. Grief doesn’t end; it transforms. Sometimes it sits quietly beside you. Other times, it swallows the whole day. I suppose I could define grief as the shadow of a jewel.&lt;/p&gt;

&lt;p&gt;The very light that fills our lives can also cast the deepest shadow when it fades. Maybe that’s the hidden curse of love — that to love deeply is to accept the risk of breaking completely. When you sign up to love and care for anyone, you are implicitly signing up to give them pain or to suffer the pain of an endless grief. Either way, we are cursed.&lt;/p&gt;

&lt;p&gt;Here’s the thing that worries me thiough, I love my kids so deeply, and I know that they love me. Now that’s a puzzle.&lt;/p&gt;

&lt;p&gt;But here’s what I’m learning to hold onto — the curse is also the blessing. Yes, grief is the price of love. Yes, it breaks us. But would I trade away the years with my mum to avoid this pain? Never. Would I love my children less to spare us all future heartbreak? Not for a second.&lt;/p&gt;

&lt;p&gt;The weight of grief is simply love with nowhere to go. It’s not the opposite of love; it’s love’s continuation in a different form. And if I must carry this shadow for the rest of my life, then so be it — because it means the light was real. She was real. This love is real.&lt;/p&gt;

&lt;p&gt;Maybe we’re not cursed after all. Maybe we’re just human. And being human means choosing to love fully, knowing the cost, and deciding it’s worth it anyway. Every single time.&lt;/p&gt;

&lt;p&gt;Yeah, vanity. everything is vanity.&lt;/p&gt;
</description>
                <pubDate>Fri, 10 Oct 2025 03:01:35 +0000</pubDate>
                <link>https://israelo.io/blog/love-is-a-curse/</link>
                <guid isPermaLink="true">https://israelo.io/blog/love-is-a-curse/</guid>
                
                <category>mum</category>
                
                <category>life</category>
                
                
                <category>personal</category>
                
            </item>
        
            <item>
                <title>User Journeys Are Dead. Enter the Agentic Journey Era</title>
                <description>&lt;p&gt;For years, product managers and founders (myself included) built products around user journeys. We mapped every click, tap, and drop-off point. We obsessed over funnels, session duration, flows, DAU (Daily Active Users), MAU (Monthly Active Users).&lt;/p&gt;

&lt;p&gt;That era is ending. The PRD structure must evolve.&lt;/p&gt;

&lt;p&gt;The next generation of &lt;strong&gt;amazing products&lt;/strong&gt; won’t be defined by users (painstakingly) clicking or tapping through flows. They’ll be powered by &lt;strong&gt;AI agentic systems&lt;/strong&gt; that understand intent, plan across platforms, and execute on behalf of the user.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://israelo.io/blog/bluf/&quot;&gt;BLUF&lt;/a&gt; is:  user journeys as we know them are fading, giving way to the &lt;strong&gt;agentic journey&lt;/strong&gt;. When designing for product, you must now consider &lt;strong&gt;AI agents&lt;/strong&gt; and how they achieve outcomes. Go further by factoring in &lt;strong&gt;token economics&lt;/strong&gt; and create &lt;strong&gt;AI eval frameworks&lt;/strong&gt; for measuring success. Traditional metrics like clicks, session duration and active sessions are headed for obsolescence, just like the journeys themselves.&lt;/p&gt;

&lt;p&gt;The future belongs to products that orchestrate outcomes, not just user interactions.&lt;/p&gt;

&lt;h1 id=&quot;why-this-hit-me&quot;&gt;Why This Hit Me&lt;/h1&gt;

&lt;p&gt;Early in my career at AppDynamics (Cisco), I spent nearly all my time onsite with customers, supporting both pre-sales and post-sales activities (depending on the quarter). Sitting shoulder to shoulder, I could see every hesitation, every workaround, every aha moment. That intimacy shaped how I thought about product.&lt;/p&gt;

&lt;p&gt;During COVID, when I moved into product management full-time, that contact disappeared. PRDs, metrics, and dashboards replaced real-time user insight. FWIW, user interviews are never the same as watching users interact with your product—their body language, the subtle patterns in how they work—you notice things you can never capture in Zoom meetings, metrics, or dashboards.&lt;/p&gt;

&lt;p&gt;Recently, onsite with a &lt;a href=&quot;https://zymtrace.com&quot;&gt;&lt;strong&gt;zymtrace&lt;/strong&gt;&lt;/a&gt; customer, I felt that old rush again. What struck me wasn’t just how people used the product, but how naturally they leaned on &lt;strong&gt;AI agents&lt;/strong&gt; in their IDEs, CLIs, and workflows. Tasks that once required manual steps were now offloaded to agents. It drove home a truth: &lt;strong&gt;the way we build and measure products has to evolve.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The contrast between these experiences—then and now—makes one thing absolutely clear: product design is no longer just about user interaction; it must now include considerations on how AI agents can achieve the intended outcome. We must rethink product success metrics.&lt;/p&gt;

&lt;h2 id=&quot;what-really-is-the-agentic-journey&quot;&gt;What Really Is the Agentic Journey?&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Agentic journeys&lt;/strong&gt; are fundamentally different from traditional user flows. Unlike conventional journeys, they don’t require users to follow predefined paths—they understand the user’s goals from the outset. Agents interpret intent, navigate complexity, and execute tasks on behalf of the user, turning multi-step workflows into seamless outcomes.&lt;/p&gt;

&lt;p&gt;When I say &lt;strong&gt;agent&lt;/strong&gt; here, I mean an AI system that, once given a goal, autonomously chooses its next step—selecting and invoking tools, planning or revising its approach, and using real-world feedback (API responses, errors, intermediate state) to iteratively reach an outcome instead of executing a fixed, hardcoded sequence (&lt;a href=&quot;https://www.anthropic.com/engineering/building-effective-agents&quot;&gt;ref: Anthropic: Building effective agents&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Key characteristics of agentic journeys include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Fewer apps, fewer tabs&lt;/strong&gt; — Agents eliminate context-switching by fetching, integrating, and delivering results directly. Users no longer juggle multiple windows; the agent handles it.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Agent-to-agent communication&lt;/strong&gt; — Agents coordinate with one another to delegate tasks and orchestrate workflows. Workflows become a collaborative mesh of agents, not a linear sequence of clicks.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Adaptive workflows&lt;/strong&gt; — Agents adjust plans in real-time as goals or data change, rather than following rigid, predefined paths.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Cost per outcome matters&lt;/strong&gt; — Efficiency is critical. Excessive compute, tokens, or latency can break the journey.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, the &lt;a href=&quot;https://developers.googleblog.com/en/a2a-a-new-era-of-agent-interoperability&quot;&gt;&lt;strong&gt;Agent2Agent (A2A) Protocol&lt;/strong&gt;&lt;/a&gt;, introduced by Google in April 2025, enables secure communication and collaboration between AI agents across different platforms and vendors. It allows them to share context and coordinate actions seamlessly. Additionally, the &lt;a href=&quot;https://cloud.google.com/blog/products/ai-machine-learning/announcing-agents-to-payments-ap2-protocol&quot;&gt;&lt;strong&gt;Agent Payments Protocol (AP2)&lt;/strong&gt;&lt;/a&gt;, announced in September 2025, provides a standardized framework for secure, compliant transactions conducted by AI agents on behalf of users.&lt;/p&gt;

&lt;p&gt;These protocols illustrate how agentic AI systems are evolving to manage complexity, collaborate autonomously, and perform transactions securely.&lt;/p&gt;

&lt;h2 id=&quot;product-metrics-must-change-too&quot;&gt;Product Metrics Must Change Too&lt;/h2&gt;

&lt;p&gt;When I was at Elastic (as Principal Product Manager), I managed BI for a while. I spent a lot of time diving into metrics: MAU, DAU, product segmentation, retention curves. We lived and died by understanding how users moved through the product.&lt;/p&gt;

&lt;p&gt;If I were to do it all over again, my approach would be different. The questions aren’t “How many people logged in today?” or “Which feature saw the most clicks?” Instead, they become:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Did the &lt;strong&gt;agent&lt;/strong&gt; complete the intended outcome?&lt;/li&gt;
  &lt;li&gt;How many &lt;strong&gt;tokens&lt;/strong&gt; did it cost to get there?&lt;/li&gt;
  &lt;li&gt;Did the product provide the &lt;strong&gt;right context&lt;/strong&gt;, quickly and efficiently?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are &lt;strong&gt;outcome-based metrics&lt;/strong&gt;—they reflect the economic reality of building in an agentic world. Engagement for its own sake doesn’t matter anymore. What matters is &lt;strong&gt;efficiency&lt;/strong&gt; and &lt;strong&gt;cost per completed outcome&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To make these metrics actionable, I’d build evals to measure success: automated tests, benchmarks, and simulations that validate whether agents achieve outcomes reliably, efficiently, and safely. This shifts the focus from counting clicks or logins to understanding real impact.&lt;/p&gt;

&lt;h2 id=&quot;token-economics-and-efficiency&quot;&gt;Token Economics and Efficiency&lt;/h2&gt;

&lt;p&gt;Agents don’t run for free. Every reasoning step, API call, and chunk of text processed burns tokens—and tokens translate directly into dollars.&lt;/p&gt;

&lt;p&gt;That means product teams can’t just design for functionality. We need to design for &lt;strong&gt;economic viability&lt;/strong&gt;. How many tokens does it take to reach an outcome? Is the workflow efficient enough to scale?&lt;/p&gt;

&lt;p&gt;APIs sit at the center of this. Agents don’t care about a beautiful UI—they care about clean, reliable endpoints. That means:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Expose everything via API&lt;/strong&gt; — Every product feature available to a user should also be accessible programmatically.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Predictable responses&lt;/strong&gt; — Agents need consistency, not cleverness.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Minimal payloads&lt;/strong&gt; — Return only what’s necessary. Bloated responses waste tokens and context.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Composable endpoints&lt;/strong&gt; — Agents should be able to chain actions without brittle hacks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Products that ignore these principles will quickly become too expensive to use. Products that design for &lt;strong&gt;compression, context, and efficiency&lt;/strong&gt; will win.&lt;/p&gt;

&lt;p&gt;Gartner’s research underscores this point: more than 40% of agentic AI projects are expected to be scrapped by 2027 because costs spiral out of control and business value remains unclear (&lt;a href=&quot;https://www.reuters.com/business/over-40-agentic-ai-projects-will-be-scrapped-by-2027-gartner-says-2025-06-25&quot;&gt;Reuters&lt;/a&gt;). In other words, ignoring token economics isn’t just inefficient—it can be fatal to the viability of entire product lines.&lt;/p&gt;

&lt;p&gt;Anthropic’s &lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt; is an early signal of what’s coming. It shows how agents can manage multi-step processes across tools in a structured, context-aware way.&lt;/p&gt;

&lt;p&gt;This isn’t just a technical shift—it’s a &lt;strong&gt;product strategy shift&lt;/strong&gt;. The ecosystem is moving toward &lt;strong&gt;interoperability&lt;/strong&gt; and &lt;strong&gt;agent-first design&lt;/strong&gt;, where efficiency and cost per outcome drive product decisions.&lt;/p&gt;

&lt;h2 id=&quot;what-you-must-now-do&quot;&gt;What You Must Now Do&lt;/h2&gt;

&lt;p&gt;If you’re building or leading product today, here’s where I’d start:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Audit your APIs&lt;/strong&gt; — Can an agent realistically complete your core use case?&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Re-examine pricing and unit economics&lt;/strong&gt; — Factor in token costs and operational efficiency.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Position your product as part of an agent-driven ecosystem&lt;/strong&gt; — Don’t treat it as a standalone UI.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Train your team to think in “agentic journeys”&lt;/strong&gt; — Go beyond traditional user flows.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Redefine your metrics&lt;/strong&gt; — Measure outcomes and token efficiency, not just logins and clicks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;closing-thought&quot;&gt;Closing Thought&lt;/h2&gt;

&lt;p&gt;Watching customers use &lt;a href=&quot;https://zymtrace.com&quot;&gt;&lt;strong&gt;zymtrace&lt;/strong&gt;&lt;/a&gt; in real time reminded me that building product is never static.&lt;/p&gt;

&lt;p&gt;We must shift, albeit gradually, from product journeys designed for people to journeys carried out by AI agents. It’s a new model, and if we don’t adapt, our products won’t just feel clunky; they’ll risk becoming irrelevant.&lt;/p&gt;

&lt;p&gt;The next time you discuss product user journeys with your peers or team, ask: &lt;em&gt;What does the agentic journey look like, and how do we build evals to measure its success?&lt;/em&gt;&lt;/p&gt;
</description>
                <pubDate>Tue, 30 Sep 2025 03:01:35 +0000</pubDate>
                <link>https://israelo.io/blog/agentic-journey/</link>
                <guid isPermaLink="true">https://israelo.io/blog/agentic-journey/</guid>
                
                <category>ai</category>
                
                <category>cloud-native</category>
                
                
                <category>Cloud Native</category>
                
            </item>
        
            <item>
                <title>Code &amp; Communication: The Keys My 8-Year-Old Uses to Design Apps</title>
                <description>&lt;blockquote&gt;
  &lt;p&gt;“The success or failure of a product strongly depends on the user experience”, By Rochelle Ogbole&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’m constantly amazed by my daughter Rochelle, and today was no exception 🤩. At just 8 years old, she’s already thinking up ideas for mobile apps, explaining them with a level of clarity that could rival a seasoned developer. But maybe I shouldn’t be too surprised—after all, she’s been coding on Scratch since she was 4! 👩‍💻&lt;/p&gt;

&lt;p&gt;Recently, Rochelle came up with a brilliant concept: a kid-friendly mobile app that serves as a creativity canvas for children. Her idea? To unlock kids’ imaginations and bring their creativity to life in a fun, interactive way. We discussed what motivates her to create this app, and I was blown away by how well-thought-out her vision was 😲. It was like she had been planning this for years.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I didn’t expect the Twitter to X reaction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;She wants kids to be able to share their creations on social media as a feature. The look on her face when I told her that Twitter is now called X was priceless—she was genuinely surprised. &lt;em&gt;“Why would they do that? What does ‘X’ even mean?” she asked. Then she added, “Well, I’m going to stick with Twitter, Daddy.”&lt;/em&gt; I’ll respect her opinion on that!&lt;/p&gt;

&lt;p&gt;Watch the trailer for yourself.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/lih4yXVza7M?si=zPy8YCFKaIDr1UHv&quot; title=&quot;Rochelle App&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;h2 id=&quot;wireframing-her-vision&quot;&gt;Wireframing Her Vision&lt;/h2&gt;

&lt;p&gt;To start the process, we wireframed her app on paper ✏️. Rochelle took charge, sketching out how the app would look and function. I then suggested she take the next step and design it using Figma 🖥️. I wanted her to get feedback from her friends and their parents, curious to see if they would pay for such an app 💡.&lt;/p&gt;

&lt;p&gt;I created a Figma account for her, and then I headed off to the gym 🏋️‍♂️, giving her the space to experiment on her own. What happened next truly floored me 🤯. After just 1.5 hours, I returned to find that Rochelle had completely designed the app on Figma, and it looked fantastic! What’s incredible is that I didn’t even teach her how to use Figma—she explored the tool on her own, figured out all the controls, and took to it like a duck to water 🦆💦.&lt;/p&gt;

&lt;h2 id=&quot;polishing-the-design&quot;&gt;Polishing the Design&lt;/h2&gt;

&lt;p&gt;Once Rochelle finished her designs, I offered some guidance on refining them 💬. I introduced her to advanced concepts like components, instances, and prototyping (linking screens) without ever touching the mouse or keyboard. That’s one of my principles when teaching your kids o code or work with computers, never take over the controls. I firmly believe that learning by doing is the best way for skills to stick 👌.&lt;/p&gt;

&lt;p&gt;And I must say, Rochelle did an amazing job 👏. The app is designed with a user-friendly interface, perfect for kids. It’s colorful, intuitive, and fun—just what a creativity canvas for children should be 🖌️✨.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;…without ever touching the mouse or keyboard. 
That’s one of my principles when teaching your kids to code or work with computers, never take over the controls..&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p align=&quot;center&quot;&gt;
  &lt;img width=&quot;334&quot; alt=&quot;design&quot; src=&quot;https://github.com/user-attachments/assets/030164ae-6130-40ad-9498-a5fca5ed0b98&quot; /&gt;
&lt;/p&gt;

&lt;h2 id=&quot;sharing-the-experience&quot;&gt;Sharing the Experience&lt;/h2&gt;

&lt;p&gt;One thing I emphasize a lot with my kids is the importance of communication. It doesn’t matter how brilliant your idea is if you can’t present it well. Whether it’s app design, coding, or any other project, being able to clearly articulate your ideas is key to success. So, after every project, we always make time for a formal presentation. Presentation skills are as crucial as the technical ones. Rochelle not only designed this app but also put together a full pitch—explaining her thought process, the user experience, and why kids would love it 🗣️. She’s learning that creativity and communication go hand in hand, and I couldn’t be prouder of how she’s developing these skills 🤗.&lt;/p&gt;

&lt;p&gt;We even made a trailer to showcase her work! 🎥 I used iMovie to edit the video (though if anyone knows of a better or easier software for video editing, I’m all ears). Watch the full video.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/c9yjyXfYxJo?si=Ivh8Z0Fy66Hqjf2U&quot; title=&quot;Rochelle App&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;This experience has truly been an eye-opener. The future is indeed bright 🌟, especially with kids like Rochelle who are so creative and capable at such a young age 💫. Watching her dive into the world of app design with such enthusiasm and skill has made me incredibly proud 💖. Who knows, maybe this app will be the next big thing for kids!&lt;/p&gt;

&lt;p&gt;Stay tuned for more updates on Rochelle’s journey. I can’t wait to see where her creativity takes her next! 🚀&lt;/p&gt;
</description>
                <pubDate>Tue, 03 Sep 2024 22:01:35 +0000</pubDate>
                <link>https://israelo.io/blog/chelly-app/</link>
                <guid isPermaLink="true">https://israelo.io/blog/chelly-app/</guid>
                
                <category>kids</category>
                
                <category>coding</category>
                
                <category>stem</category>
                
                
                <category>personal</category>
                
            </item>
        
            <item>
                <title>Profile-Guided Optimization: A Hands-On Guide to Reducing Computational Wastage</title>
                <description>&lt;p&gt;Over the past few months, I’ve had numerous discussions with practitioners and colleagues on the benefits of Profile-Guided Optimization (PGO). While it’s a topic that generates significant interest, many find it challenging to get started or simply lack the time to explore it fully. As a &lt;strong&gt;Product Manager&lt;/strong&gt; in the continuous profiling domain, my curiosity drove me to delve deeper into this subject. After studying various academic papers and articles, I decided to implement PGO myself, benchmarking its impact to assess its true value.&lt;/p&gt;

&lt;p&gt;My primary goal was to understand the challenges hindering PGO adoption and to identify key questions that could reveal customers’ real pain points. Additionally, I aimed to explore the business value for end users. Specifically, I wanted to quantify how PGO impacts critical business KPIs such as conversion rates, latency, and even SLOs and SLAs.&lt;/p&gt;

&lt;p&gt;This blog summarizes my initial findings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Efficient software is both cheaper and greener 🌿.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;PGO can boost your code’s efficiency by up to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;14%&lt;/code&gt; for free—without requiring any code changes.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;A practical guide to implementing PGO is presented, including insights on measuring compute and end-user performance gains using inlining output, binary size, go-wrk, and flamegraphs.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;In the example Go code provided, my analysis revealed a notable performance gain of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~ 6.92%&lt;/code&gt; in compute efficiency—an impressive result considering it’s based on a small JSON unmarshalling task. The potential savings in a production environment could be even more substantial.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Many developers and SREs are missing out on potential cost savings by not leveraging PGO. You can learn from Cloudflare’s &lt;a href=&quot;https://blog.cloudflare.com/reclaiming-cpu-for-free-with-pgo&quot;&gt;experience&lt;/a&gt; in reducing costs through PGO.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Continuous profiling in production is essential to unlock the benefits of PGO fully.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;pgo-your-codes-personal-coach-for-peak-performance&quot;&gt;PGO: Your Code’s Personal Coach for Peak Performance&lt;/h2&gt;

&lt;p&gt;Imagine you’re an athlete training for the Olympics. A generic training regimen might get you started, but it won’t fully optimize your performance. This is why most athletes hire a personal coach. A personal coach observes your training, identifies areas for improvement, and adjusts your regimen accordingly. This personalized approach leads to better results in a shorter time.&lt;/p&gt;

&lt;p&gt;PGO is like that coach for your code. It analyzes your code’s performance, identifies frequently executed code paths, and feeds that data to the compiler to refine its optimization decisions. By informing the compiler of your code’s hotspots, PGO helps your code achieve peak performance, just as a coach helps an athlete win an Olympic gold medal.&lt;/p&gt;

&lt;p&gt;To connect the dots, the way a coach observes an athlete’s training regimen and physiological components is similar to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;profiling&lt;/code&gt; in this context. Just as a coach &lt;strong&gt;scouts&lt;/strong&gt; their athletes, &lt;strong&gt;continuous profiling&lt;/strong&gt; analyzes your code’s behavior on an ongoing basis. Additionally, your &lt;strong&gt;gold&lt;/strong&gt;, as a developer or SRE, could be promotion, a reduction in carbon footprint and/or lowering cloud spend.&lt;/p&gt;

&lt;p&gt;PGO is an advanced optimization technique that leverages profiling data to guide the compiler in making more informed optimization decisions. By using PGO, the compiler can optimize hot code paths, potentially leading to significant performance improvements.&lt;/p&gt;

&lt;p&gt;Further, PGOs can improve your code’s resource utilization efficiency by up to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;14%&lt;/code&gt;. That’s a lot of cost savings in most medium - to large organizations without making any code changes, that’s free money on the table!&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;As of Go 1.22, benchmarks for a representative set of Go programs show
that building with PGO improves performance by around 2-14%. We expect
performance gains to generally increase over time as additional
optimizations take advantage of PGO in future versions of Go. 
&lt;em&gt;(source: &lt;a href=&quot;https://go.dev/doc/pgo#overview&quot;&gt;PGO Overview&lt;/a&gt;, Google)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cloudflare recently shared a &lt;a href=&quot;https://blog.cloudflare.com/reclaiming-cpu-for-free-with-pgo&quot;&gt;blog post&lt;/a&gt; detailing how they significantly reduced cloud spending by implementing PGO.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;This indicates that following the release, we’re using ~97 cores fewer
than before the release, a ~3.5% reduction.
 &lt;em&gt;(source:&lt;a href=&quot;https://blog.cloudflare.com/reclaiming-cpu-for-free-with-pgo&quot;&gt;Colin Douch&lt;/a&gt;, Cloudflare)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img width=&quot;1510&quot; alt=&quot;prom&quot; src=&quot;https://github.com/user-attachments/assets/cb6c174b-7d05-49ad-b464-0247e26d9c89&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Comparing the before and after flamegraphs of PGO. See details in the results section below&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;compilers-and-the-one-size-fits-all-problem&quot;&gt;Compilers and the One-Size-Fits-All Problem&lt;/h2&gt;

&lt;p&gt;As described in the athlete analogy above (inspired by the recent 2024 Paris Olympics), one of the compiler’s primary tasks is to make optimal decisions about your code during compilation. Compilers come equipped with heuristics that guide various optimization techniques—such as dead code elimination, register allocation, constant folding, and function inlining. These strategies are designed to streamline your code and enhance its efficiency.&lt;/p&gt;

&lt;p&gt;However, the heuristics that guide the compiler’s decisions have the same problem inherent in most one-size-fits-all designs. There are limits to what a compiler can do on its own. For example, while inlining functions can reduce the overhead of function calls, the compiler can’t inline everything. Inlining too much can lead to bloated binaries, increased cache usage, and ultimately, performance degradation.&lt;/p&gt;

&lt;p&gt;This is where PGO comes in. By providing the compiler with profiling data—information about how your code actually runs in real-world scenarios—the compiler can make more informed decisions. It can identify the “hot” functions that are frequently called and optimize them more aggressively, such as by inlining these critical functions or better allocating registers. This targeted optimization helps reduce the overhead of function calls and can lead to significant performance gains. PGO allows the compiler to go beyond generic optimizations, tailoring the final binary to the specific needs of your program based on actual usage.&lt;/p&gt;

&lt;h2 id=&quot;how-does-pgo-work&quot;&gt;How does PGO work?&lt;/h2&gt;

&lt;p&gt;Several other languages support PGO. See &lt;a href=&quot;#laguages_that_support_pgo&quot;&gt;Laguages that Support PGO&lt;/a&gt; section. In this example, let’s consider a simple Go application that unmarshals JSON data containing personal bios. The application reads data from a file, processes it, and then serves it over HTTP. Here’s the code https://github.com/iogbole/go-pgo&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;encoding/json&quot;&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;fmt&quot;&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;log&quot;&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;net/http&quot;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;net/http/pprof&quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Import pprof for profiling&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;os&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BioWrapper&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;Bio&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bio&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;bio&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;`&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//truncated &lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// extractNames is a leaf function that processes course names.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extractNames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;make&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([]&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;range&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;names&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;names&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// Set up the HTTP server with pprof enabled&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HandleFunc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;processor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Starting server on :8080&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ListenAndServe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;:8080&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// processor handles incoming HTTP requests, processes the JSON, and returns the JSON data.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;processor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ResponseWriter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// Read the JSON file&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReadFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;./bio.json&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Error reading bio.json&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StatusInternalServerError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Unmarshal the JSON into the BioWrapper struct&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bioWrapper&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BioWrapper&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Unmarshal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bioWrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Error decoding JSON&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StatusBadRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Access the Bio data&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;bio&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bioWrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bio&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Process the Bio data (e.g., print to console)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Name:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PersonalInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;University:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Education&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;University&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SchoolName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Current Job:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WorkExperience&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Job2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Use the leaf function to extract course names&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;courseNames&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extractNames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Education&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;University&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Courses&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Courses:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;courseNames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Set the response header to indicate JSON content&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Content-Type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;application/json&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Using json.MarshalIndent for pretty-printing&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;responseData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MarshalIndent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bioWrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;    &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Error encoding JSON&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StatusInternalServerError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;responseData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;step-1-compile-and-run-without-pgo&quot;&gt;&lt;strong&gt;Step 1: Compile and Run Without PGO&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;First, let’s compile the program &lt;strong&gt;without PGO&lt;/strong&gt; and see how it performs under load.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;build&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;o&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pre_pgo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gcflags&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;-m&quot;&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;go&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pre_pgo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;step-2-load-testing-with-go-wrk&quot;&gt;&lt;strong&gt;Step 2: Load Testing with go-wrk&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;To simulate real-world usage, we can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go-wrk&lt;/code&gt;, a Go-based benchmarking tool, to send concurrent HTTP requests to the service. Install it from &lt;a href=&quot;https://github.com/tsliwowicz/go-wrk&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wrk&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;//localhost:8080&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This command runs the load test for 60 seconds, generating HTTP requests to the server. The results will give us a baseline of how the program performs without PGO.&lt;/p&gt;

&lt;h4 id=&quot;step-3-generate-profiling-data&quot;&gt;&lt;strong&gt;Step 3: Generate Profiling Data&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;While that’s running, let’s profile the code for 30 seconds.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;o&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pgo&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;http://localhost:8080/debug/pprof/profile?seconds=30&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;default.pgo&lt;/code&gt; is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pprof&lt;/code&gt; output. An alternative approach is to use the pprof tool.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pprof&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prof&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;//localhost:8080/debug/pprof/profile?seconds=60&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;step-4-compile-and-run-post-pgo&quot;&gt;&lt;strong&gt;Step 4: Compile and Run post PGO&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Now, let’s compile the code with PGO enabled using the profiling data we collected:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;build&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;o&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post_pgo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pgo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gcflags&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;-m&quot;&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;go&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;post_pgo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;step-5-add-load-and-profile&quot;&gt;&lt;strong&gt;Step 5: Add load and Profile&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Similar to step 3, generate load and profile - but this time, change the output of the curl to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;post_pgo.pprof&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;o&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post_pgo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pprof&lt;/span&gt;  &lt;span class=&quot;s&quot;&gt;&quot;http://localhost:8080/debug/pprof/profile?seconds=30&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;the-results&quot;&gt;The Results!!&lt;/h2&gt;

&lt;p&gt;This was my first experience with PGO, and I was eager to see if it was worth the effort. I’ve saved all the raw benchmark files in the GitHub &lt;a href=&quot;https://github.com/iogbole/go-pgo&quot;&gt;repository&lt;/a&gt; for future comparisons.&lt;/p&gt;

&lt;p&gt;Let’s begin!&lt;/p&gt;

&lt;h3 id=&quot;inlining-optimization-analysis&quot;&gt;Inlining Optimization Analysis&lt;/h3&gt;

&lt;p&gt;Inlining is a compiler optimization technique that directly inserts the body of a function into the calling code, eliminating function call overhead and potentially enabling further optimizations.&lt;/p&gt;

&lt;h4 id=&quot;binary-size-inlining-has-a-small-storage-cost&quot;&gt;Binary Size: Inlining Has a Small Storage Cost&lt;/h4&gt;

&lt;p&gt;A quick way to check for better inlining is to examine the binary size. While inlining can improve performance, it may increase the binary size due to code duplication.&lt;/p&gt;

&lt;p&gt;Let’s check it out:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;atrl&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rwxr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;israel&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;staff&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8162050&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Aug&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;45&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pre_pgo&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rwxr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;israel&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;staff&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8244658&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Aug&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;52&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post_pgo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The difference in file sizes between the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pre_pgo&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;post_pgo&lt;/code&gt; binaries can be summarized as follows:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;&lt;strong&gt;File&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Size&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Difference&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Analysis&lt;/strong&gt;&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pre_pgo&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;8,162,050 bytes&lt;/td&gt;
      &lt;td&gt;N/A&lt;/td&gt;
      &lt;td&gt;This is the size of the binary before applying PGO.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;post_pgo&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;8,244,658 bytes&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;82,608 bytes larger&lt;/strong&gt;   i.e ~ &lt;strong&gt;1.01%&lt;/strong&gt; larger&lt;/td&gt;
      &lt;td&gt;The binary size increased slightly after PGO, likely due to additional inlining and optimizations.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4 id=&quot;analysis-of-the-compiler-output&quot;&gt;Analysis of the compiler output&lt;/h4&gt;

&lt;blockquote&gt;
  &lt;p&gt;For the record, I nearly jumped out of my chair when I realized that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;processor&lt;/code&gt; function was inlined. It makes all the difference, especially as it’s a leaf function.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s dig a bit deeper by comparing the build outputs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before PGO&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/716fbe90-7435-4a5c-bbe5-f23def0e0e6a&quot; alt=&quot;carbon (4)&quot; /&gt;
&lt;em&gt;Refer to the &lt;a href=&quot;https://github.com/iogbole/go-pgo/tree/main/benchmarks&quot;&gt;repo&lt;/a&gt; for the full build output&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now let’s compare the compiler output for PGO.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After PGO&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/e1ac8aee-06be-4a2e-a80a-619c4baa7174&quot; alt=&quot;post_pgo&quot; /&gt;
&lt;em&gt;Refer to the &lt;a href=&quot;https://github.com/iogbole/go-pgo/tree/main/benchmarks&quot;&gt;repo&lt;/a&gt; for the full build output&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The inlining optimization looks way better!  Here’s a table comparing the key differences between the compiler output with and without PGO, based on the provided &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gcflags=&quot;-m&quot;&lt;/code&gt; output:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;&lt;strong&gt;Metric&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Post PGO&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Pre PGO&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Difference&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Analysis&lt;/strong&gt;&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Inlining&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extractNames&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fmt.Println&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http.ListenAndServe&lt;/code&gt;, etc.&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extractNames&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;processor&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http.(*response).Write&lt;/code&gt;, etc.&lt;/td&gt;
      &lt;td&gt;More functions inlined, including &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;processor&lt;/code&gt; and HTTP response writes&lt;/td&gt;
      &lt;td&gt;More extensive inlining in PGO due to better optimization hints&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Parameter Leaks&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Multiple parameters escape to the heap&lt;/td&gt;
      &lt;td&gt;Similar, with some optimizations such as better handling in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extractNames&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Slight improvement in handling heap allocation in PGO&lt;/td&gt;
      &lt;td&gt;PGO provides better guidance for optimizing heap allocations&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Moved to Heap&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Variables like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bios&lt;/code&gt; moved to heap&lt;/td&gt;
      &lt;td&gt;Variables like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bioWrapper&lt;/code&gt; moved to heap&lt;/td&gt;
      &lt;td&gt;Slight change in what gets moved to heap&lt;/td&gt;
      &lt;td&gt;Heap allocations are slightly optimized with PGO, but not eliminated&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;PGO Devirtualization&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Not applicable&lt;/td&gt;
      &lt;td&gt;PGO devirtualizes interface calls&lt;/td&gt;
      &lt;td&gt;Devirtualization is applied&lt;/td&gt;
      &lt;td&gt;PGO enables devirtualization, improving performance by optimizing interface calls&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Leaking Param&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;w&lt;/code&gt;, etc. escape to heap&lt;/td&gt;
      &lt;td&gt;Similar parameters leak but with better optimizations such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extractNames&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Slight reduction in the number of heap escapes&lt;/td&gt;
      &lt;td&gt;PGO guides more efficient memory management, but some leaks persist&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;flamegrapsh-analysis&quot;&gt;Flamegrapsh analysis&lt;/h3&gt;

&lt;p&gt;Using &lt;a href=&quot;https://www.speedscope.app&quot;&gt;https://www.speedscope.app&lt;/a&gt;, I uploaded the before and after pprof files for quick analysis. Since Speedscope lacks a differential flamegraph feature, I compared both flamegraphs side-by-side.&lt;/p&gt;

&lt;p&gt;But first, let’s identify the top functions and verify the weight of the callers and callees.&lt;/p&gt;

&lt;p&gt;&lt;img width=&quot;1641&quot; alt=&quot;sandwitch&quot; src=&quot;https://github.com/user-attachments/assets/78659f47-22a5-4049-885f-f46854d98211&quot; /&gt;
&lt;em&gt;The sandwitch view - showing callers and callees&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The sandwich view shows that we need to focus on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main.processor&lt;/code&gt; function, which is somewhat expected.  Let’s verify this hypothesis with a flamegraph.&lt;/p&gt;

&lt;p&gt;&lt;img width=&quot;2800&quot; alt=&quot;speedscope&quot; src=&quot;https://github.com/user-attachments/assets/c362a17c-ee13-423d-b1cf-22b455e9531c&quot; /&gt;
&lt;em&gt;Differential flamegraphs&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The table below summarizes the analysis of the before and after PGO flamegraphs&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;&lt;strong&gt;Metric&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Pre PGO (Left)&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Post PGO (Right)&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Time Gained/Lost&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Percentage Improvement&lt;/strong&gt;&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main.processor&lt;/code&gt; Total Time&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;48.25 seconds&lt;/td&gt;
      &lt;td&gt;44.91 seconds&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;3.34 seconds gained&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;6.92% improvement&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main.processor&lt;/code&gt; Self Time&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;10.00ms&lt;/td&gt;
      &lt;td&gt;0.00ns&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;10.00ms gained&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;100% improvement&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;HTTP Handler Functions Total Time&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Higher&lt;/td&gt;
      &lt;td&gt;Lower&lt;/td&gt;
      &lt;td&gt;Not Quantified&lt;/td&gt;
      &lt;td&gt;Slight improvement (qualitative)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Syscall Execution Time&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Higher&lt;/td&gt;
      &lt;td&gt;Lower&lt;/td&gt;
      &lt;td&gt;Not Quantified&lt;/td&gt;
      &lt;td&gt;Slight improvement (qualitative)&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Looking a bit further, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;6.92%&lt;/code&gt; improvement is most likely derived by inlining the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main.processor&lt;/code&gt; function.&lt;/p&gt;

&lt;h3 id=&quot;end-userbusiness-impact-analysis&quot;&gt;End-user/business impact analysis&lt;/h3&gt;

&lt;p&gt;The flamegraph analysis revealed a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;6.92%&lt;/code&gt; improvement in overall code efficiency. While this is a substantial gain, especially considering cloud costs, it’s crucial to understand how it translates into real-world benefits for end users.
To quantify the impact, I turned to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go-wrk&lt;/code&gt; benchmarking data, located &lt;a href=&quot;https://github.com/iogbole/go-pgo/tree/main/benchmarks/wrk_benchmark.txt&quot;&gt;here&lt;/a&gt;. By analyzing these metrics, I can assess the practical performance improvements that users will experience.
Let’s delve into the details and see how these optimizations translate into tangible benefits&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Baseline Pre_PGO output&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/48e4391d-9be7-43db-a8e9-bf56425c54fd&quot; alt=&quot;before&quot; /&gt;&lt;/p&gt;

&lt;p&gt;and the &lt;strong&gt;comparison post pgo go-wrk result&lt;/strong&gt; is:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/f7e1dec4-2559-43b7-9359-d1f434a47275&quot; alt=&quot;after&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Let’s delve into the details and see how these optimizations could translate to business KPIs.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;&lt;strong&gt;Metric&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Pre-PGO&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Post-PGO&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Difference&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Percentage Gain/Loss&lt;/strong&gt;&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Total Requests&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;1,557,674&lt;/td&gt;
      &lt;td&gt;1,626,603&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+68,929 requests&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+4.43%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Total Data Transferred&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;1.47 GB&lt;/td&gt;
      &lt;td&gt;1.54 GB&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+0.07 GB&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+4.76%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Requests/sec&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;26,100.68&lt;/td&gt;
      &lt;td&gt;27,257.19&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+1,156.51 requests/sec&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+4.43%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Transfer/sec&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;25.29 MB&lt;/td&gt;
      &lt;td&gt;26.41 MB&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+1.12 MB/sec&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+4.43%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Overall Requests/sec&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;25,959.83&lt;/td&gt;
      &lt;td&gt;27,108.41&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+1,148.58 requests/sec&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+4.42%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Overall Transfer/sec&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;25.15 MB&lt;/td&gt;
      &lt;td&gt;26.27 MB&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+1.12 MB/sec&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+4.45%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Fastest Request&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;65 µs&lt;/td&gt;
      &lt;td&gt;66 µs&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+1 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;-1.54%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Average Request Time&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;382 µs&lt;/td&gt;
      &lt;td&gt;366 µs&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;-16 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+4.19%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Slowest Request&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;56.609 ms&lt;/td&gt;
      &lt;td&gt;57.569 ms&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+0.960 ms&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;-1.70%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Standard Deviation&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;651 µs&lt;/td&gt;
      &lt;td&gt;655 µs&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+4 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;-0.61%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;percentile-response-times&quot;&gt;&lt;strong&gt;Percentile Response Times&lt;/strong&gt;&lt;/h3&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;&lt;strong&gt;Percentile&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Pre-PGO&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Post-PGO&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Difference&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Percentage Gain/Loss&lt;/strong&gt;&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;10%&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;82 µs&lt;/td&gt;
      &lt;td&gt;80 µs&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;-2 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+2.44%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;50%&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;90 µs&lt;/td&gt;
      &lt;td&gt;88 µs&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;-2 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+2.22%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;75%&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;94 µs&lt;/td&gt;
      &lt;td&gt;90 µs&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;-4 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+4.26%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;99%&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;96 µs&lt;/td&gt;
      &lt;td&gt;92 µs&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;-4 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+4.17%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;99.9%&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;97 µs&lt;/td&gt;
      &lt;td&gt;92 µs&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;-5 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+5.15%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;99.9999%&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;97 µs&lt;/td&gt;
      &lt;td&gt;92 µs&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;-5 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+5.15%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;99.99999%&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;97 µs&lt;/td&gt;
      &lt;td&gt;92 µs&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;-5 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;+5.15%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;In summary:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Requests/sec&lt;/strong&gt; and &lt;strong&gt;Total Data Transferred&lt;/strong&gt; saw a &lt;strong&gt;+4.43%&lt;/strong&gt; and &lt;strong&gt;+4.76%&lt;/strong&gt; improvement, respectively.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Average Request Time&lt;/strong&gt; decreased by &lt;strong&gt;16 µs&lt;/strong&gt;, showing a &lt;strong&gt;+4.19%&lt;/strong&gt; improvement.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Slowest Request&lt;/strong&gt; and &lt;strong&gt;Fastest Request&lt;/strong&gt; showed minor changes with slight percentage losses.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Percentile Response Times&lt;/strong&gt; improved across the board, with the most significant gains in the higher percentiles, up to &lt;strong&gt;+5.15%&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These results highlight the performance improvements achieved with PGO, reflected in better throughput and reduced latency.&lt;/p&gt;

&lt;p&gt;What’s not to like?&lt;/p&gt;

&lt;h2 id=&quot;laguages-that-support-pgo&quot;&gt;Laguages that support PGO&lt;/h2&gt;

&lt;p&gt;PGO is supported by many popular programming languages and compilers. Key examples include:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;C/C++&lt;/strong&gt;: Supported by GCC, Clang/LLVM, and MSVC with options like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-fprofile-generate&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-fprofile-use&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/LTCG:PGOptimize&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Go&lt;/strong&gt;: Available from Go 1.20, using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pprof&lt;/code&gt; tool for profiling.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Rust&lt;/strong&gt;: Supported via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rustc&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Cprofile-generate&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Cprofile-use&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Java&lt;/strong&gt;: Optimized by Oracle HotSpot JVM and GraalVM through JIT compilation.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;.NET&lt;/strong&gt;: The .NET Runtime uses PGO to optimize JIT compilation.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Swift&lt;/strong&gt;: Leverages LLVM’s PGO infrastructure.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Python&lt;/strong&gt;: CPython can be compiled with PGO using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./configure --enable-optimizations&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Fortran&lt;/strong&gt;: Supported in GFortran as part of GCC with the same options as C/C++.  &lt;em&gt;Does anyone still write Fortran code?&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;This blog post explored Profile-Guided Optimization (PGO) and its potential benefits for improving code performance.&lt;/p&gt;

&lt;p&gt;We used a simple Go application as an example, demonstrating the steps involved in applying PGO:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Compile and Run Without PGO&lt;/strong&gt;: Establish a baseline performance metric.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Load Testing&lt;/strong&gt;: Simulate real-world usage with tools like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go-wrk&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Generate Profiling Data&lt;/strong&gt;: Capture runtime behavior using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pprof&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Compile and Run with PGO&lt;/strong&gt;: Leverage profiling data for optimizations.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Analyze Results&lt;/strong&gt;: Compare performance improvements and assess optimizations through techniques like flamegraph analysis.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The example showcased potential performance gains through PGO, including reduced execution time and optimized memory management. It’s important to note that specific results may vary depending on the application and the profiling data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why aren’t more developers leveraging the power of PGO?&lt;/strong&gt; Please share your thoughts in the comments.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://go.dev/doc/pgo#overview&quot;&gt;Profile-Guided Optimization (PGO) Overview - Go&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://research.nvidia.com/publication/2021-07_cooperative-profile-guided-optimization&quot;&gt;Cooperative Profile-Guided Optimization - NVIDIA Research&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/google/autofdo&quot;&gt;AutoFDO - Google&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.researchgate.net/publication/222669095_PGO_a_Parallel_Computing_Platform_for_Global_Optimization_Based_on_Genetic_Algorithm&quot;&gt;PGO: A Parallel Computing Platform for Global Optimization Based on Genetic Algorithm - ResearchGate&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
                <pubDate>Tue, 27 Aug 2024 23:01:35 +0000</pubDate>
                <link>https://israelo.io/blog/pgo/</link>
                <guid isPermaLink="true">https://israelo.io/blog/pgo/</guid>
                
                <category>containers</category>
                
                <category>devops</category>
                
                <category>cloud-native</category>
                
                <category>kubernetes</category>
                
                
                <category>Cloud Native</category>
                
            </item>
        
            <item>
                <title>Stack Walking Without Frame Pointers Was a Pain – But Not Anymore!</title>
                <description>&lt;blockquote&gt;
  &lt;p&gt;The omission of frame pointers complicated stack walking, but .eh_frame data now allows accurate stack unwinding without debug symbols. With Fedora and Ubuntu re-enabling frame pointers, profiling and debugging have become much easier and more efficient.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;the-importance-of-frame-pointers-in-sampling-profilers&quot;&gt;The Importance of Frame Pointers in Sampling Profilers&lt;/h3&gt;

&lt;p&gt;A sampling profiler periodically instructs the operating system to collect data about the running processes, typically multiple times per second per CPU core. Each time the profiler gets control, it performs a “stack walk.” This means it analyzes the call stack from the current location where the CPU is executing, tracing back through the function calls to determine the sequence of code that led to that point.&lt;/p&gt;

&lt;p&gt;This stack walking helps answer crucial questions: “Where are we currently spending our time?” and “How did we get here?” Historically, performing such stack walks was straightforward, but modern compiler optimizations and architectural complexities have made it much more challenging.&lt;/p&gt;

&lt;h4 id=&quot;stack-walking&quot;&gt;Stack Walking&lt;/h4&gt;

&lt;p&gt;In the good ol’ days, x86 compilers used a predictable set of assembly instructions (the “standard function prologue”) to manage the stack and frame pointers. This made it a breeze to walk the stack and understand the call sequence. Think of it like having a clear map with marked landmarks.&lt;/p&gt;

&lt;p&gt;Here’s an example of that prologue:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;push&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ebp&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;mov&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ebp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;esp&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sub&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;esp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;variables&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3992a1b21e5f0910/6390d8002851885ebf7469f9/blog-elastic-stack-data.png&quot; alt=&quot;enter image description here&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The frame pointer (EBP) used to be a critical register that pointed to the base of the stack frame, allowing easy retrieval of the function call sequence. This method ensured that we could trace the execution path accurately by following these pointers. However, the advent of more advanced compiler optimizations has complicated this process.&lt;/p&gt;

&lt;h4 id=&quot;the-problem-of-omitted-frame-pointers&quot;&gt;The Problem of Omitted Frame Pointers&lt;/h4&gt;

&lt;p&gt;The x86 architecture had a limited number of general-purpose registers. To improve performance, compiler engineers realized they could free up the frame pointer for general computations by omitting its use and keeping track of the stack pointer (ESP) instead. This optimization, known as frame pointer omission, provided a significant performance boost but at the cost of complicating stack unwinding for profilers.&lt;/p&gt;

&lt;p&gt;The rationale behind this trade-off was that developers needing to debug production binaries would use debug symbols, which provide additional data to track the stack pointer’s position. However, this assumption doesn’t hold well for profiling, where simple stack walking without debug symbols is essential.&lt;/p&gt;

&lt;h4 id=&quot;the-impact-on-profiling&quot;&gt;The Impact on Profiling&lt;/h4&gt;

&lt;p&gt;The omission of frame pointers breaks the ability of sampling profilers to unwind native stacks through third-party libraries. Even if your code is compiled with frame pointers, any call into a library without them (e.g., libc for memory allocation) disrupts the profiling, rendering the profiler unable to trace the call sequence accurately.&lt;/p&gt;

&lt;p&gt;This issue is pervasive as most major Linux distributions ship libraries compiled with frame pointer omission, breaking simple stack walking for profiling. The common workarounds—recompiling libraries without frame pointer omission or deploying debug symbols—are impractical for many organizations due to the complexity and overhead involved.&lt;/p&gt;

&lt;h4 id=&quot;eh_frames-to-the-rescue&quot;&gt;.eh_frames to the rescue&lt;/h4&gt;

&lt;p&gt;The challenge lies in finding a way to profile systems effectively without the need for debug symbols or recompilation. Our approach, with Elastic Universal Profiling,  leverages C++ exception handling data embedded in executables. This data, present due to the need for stack unwinding during exception handling, is available even in non-C++ projects to ensure interoperability.&lt;/p&gt;

&lt;p&gt;By using this data, we can perform full stack unwinding without relying on debug symbols. This involves reading the .eh_frame section of executables, which contains the necessary unwinding information. Our solution uses eBPF (Extended Berkeley Packet Filter) to manage this process efficiently. When our eBPF code encounters an executable compiled without frame pointers, it signals our userspace agent to read the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.eh_frame&lt;/code&gt; section and convert it into a more manageable data structure. This data is then provided back to the kernel code, enabling rapid stack unwinding.&lt;/p&gt;

&lt;h4 id=&quot;framepointers-are-back&quot;&gt;Framepointers are back&lt;/h4&gt;

&lt;p&gt;The good news is, framepointer are back again by default.&lt;/p&gt;

&lt;p&gt;Following &lt;a href=&quot;https://www.phoronix.com/news/F38-fno-omit-frame-pointer&quot;&gt;Fedora deciding to enable frame pointers by default&lt;/a&gt;  for their package builds to help debugging and profiling with the stock packages, Ubuntu Linux is now going to be doing the same.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/e758d98f-e2d3-4b7a-9558-098a6ad30d60&quot; alt=&quot;enter image description here&quot; /&gt;
*source &lt;a href=&quot;https://www.phoronix.com/news/Ubuntu-Frame-Pointers-Default&quot;&gt;phoronix&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;The omission of frame pointers, while beneficial for performance, poses significant challenges for profiling. Our innovative use of C++ exception handling data provides a seamless solution for in-production profiling, ensuring accurate stack unwinding without the need for debug symbols or recompilation. This approach simplifies the profiling process, making it more accessible and effective for developers and engineers working to optimize their systems.&lt;/p&gt;

&lt;p&gt;The return of framepointers will make life significantly easier for debugging system issues.&lt;/p&gt;
</description>
                <pubDate>Fri, 26 Jul 2024 03:01:35 +0000</pubDate>
                <link>https://israelo.io/blog/ehframes/</link>
                <guid isPermaLink="true">https://israelo.io/blog/ehframes/</guid>
                
                <category>containers</category>
                
                <category>devops</category>
                
                <category>cloud-native</category>
                
                <category>kubernetes</category>
                
                <category>ebpf</category>
                
                
                <category>Cloud Native</category>
                
            </item>
        
            <item>
                <title>Symbolisation: Cracking the code with ELF and DWARF</title>
                <description>&lt;h3 id=&quot;understanding-dwarf-and-elf&quot;&gt;Understanding DWARF and ELF&lt;/h3&gt;

&lt;p&gt;Before diving into symbolisation, let’s clarify two fundamental concepts: DWARF and ELF.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;DWARF&lt;/strong&gt;: This is a standard for storing debugging information within executable files. It provides a detailed blueprint of the program’s structure, including variable types, function names, and line numbers. Essentially, it’s a map from machine code back to the original source code.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;ELF&lt;/strong&gt;: The Executable and Linkable Format (ELF) is the file format commonly used for executables, object files, and shared libraries. It encapsulates the machine code, along with metadata such as section headers and symbol tables. ELF provides the container for the DWARF information.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;the-art-of-symbolisation&quot;&gt;The Art of Symbolisation&lt;/h3&gt;

&lt;p&gt;Symbolisation is the process of converting raw memory addresses (often hexadecimal) into human-readable symbols. These symbols represent function names, file paths, and line numbers. This transformation is crucial for understanding the behavior of a program, especially when analyzing performance metrics or debugging issues.&lt;/p&gt;

&lt;h3 id=&quot;example-of-an-unsymbolised-stack-trace&quot;&gt;Example of an Unsymbolised Stack Trace&lt;/h3&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;mi&quot;&gt;345223&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;232678&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;785645&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;898902&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;These are raw memory addresses that need to be translated into meaningful symbols.&lt;/p&gt;

&lt;h3 id=&quot;example-of-a-symbolised-stack-trace&quot;&gt;Example of a Symbolised Stack Trace&lt;/h3&gt;

&lt;p&gt;A symbol in profiling is a combination of a file name, function name, and line number, uniquely identifying a line of code. A stack trace is a list of these symbols, representing a sequence of function calls ending in the currently executing function. Each line in this list is a stack frame.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;function1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;function2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;function3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;function4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This stack trace indicates that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;function4&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fileD&lt;/code&gt; at line 40 called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;function3&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fileC&lt;/code&gt; at line 30, and so on.&lt;/p&gt;

&lt;h3 id=&quot;why-symbolisation-matters&quot;&gt;Why Symbolisation Matters&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Performance Profiling&lt;/strong&gt;: By symbolising stack traces, developers can pinpoint which functions are consuming the most CPU or memory resources. This information is invaluable for optimization.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Debugging&lt;/strong&gt;: When a program crashes or behaves unexpectedly, symbolisation helps identify the exact code location causing the issue.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Incident Analysis&lt;/strong&gt;: In production environments, symbolising crash dumps or error logs aids in understanding the root cause of problems.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;the-challenge-of-symbol-less-profiling&quot;&gt;The Challenge of Symbol-Less Profiling&lt;/h3&gt;

&lt;p&gt;Traditionally, profiling required deploying applications with debug symbols, which can increase binary size and potentially impact performance. However, modern profiling tools, such as the Elastic Universal Profiling, have overcome this limitation by enabling symbolisation after the fact.&lt;/p&gt;

&lt;h3 id=&quot;how-does-it-work&quot;&gt;How Does it Work?&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Data Collection&lt;/strong&gt;: Profiling data is collected without symbols. This usually involves capturing stack traces and performance metrics.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Storage&lt;/strong&gt;: The collected data is sent to a central repository or analysis platform.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Symbol Matching&lt;/strong&gt;: The platform attempts to match the memory addresses in the stack traces with symbols from available debug information.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Symbolisation&lt;/strong&gt;: Once a match is found, the addresses are replaced with human-readable symbols.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Analysis&lt;/strong&gt;: The symbolised data can now be analyzed to identify performance bottlenecks or other issues.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;practical-example-profiling-a-go-application&quot;&gt;Practical Example: Profiling a Go Application&lt;/h3&gt;

&lt;p&gt;Imagine profiling a Go application in production without debug symbols. The profiler collects performance data, including stack traces with memory addresses. This data is then uploaded to a profiling platform. The platform attempts to match the addresses against the symbols of the deployed binary or from a symbol server. Once symbolised, the profiler can generate reports showing which Go functions are consuming the most CPU time or memory.&lt;/p&gt;

&lt;p&gt;Profilers collect these unsymbolised stack traces from native code programs and then use backend processes to associate the correct symbols, a process known as “symbolisation.”&lt;/p&gt;

&lt;p&gt;Additionally, tools like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addr2line&lt;/code&gt; are often used to perform this task manually. Here’s a basic example:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cp&quot;&gt;addr2line -e my_program 345223
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This command would attempt to translate the address &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;345223&lt;/code&gt; into a symbol using the information in the executable file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my_program&lt;/code&gt;. The output might look something like:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cp&quot;&gt;
my_program.c:123

&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Indicating that the address corresponds to line 123 in the file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my_program.c&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Understanding DWARF, ELF, and the process of symbolisation is crucial for developers aiming to optimize application performance and troubleshoot issues efficiently. By leveraging these tools and techniques, one can bridge the gap between machine-level execution and human-readable code, enabling more effective debugging and performance analysis.&lt;/p&gt;
</description>
                <pubDate>Fri, 28 Jun 2024 12:01:35 +0000</pubDate>
                <link>https://israelo.io/blog/symbolise/</link>
                <guid isPermaLink="true">https://israelo.io/blog/symbolise/</guid>
                
                <category>containers</category>
                
                <category>devops</category>
                
                <category>cloud-native</category>
                
                <category>kubernetes</category>
                
                <category>ebpf</category>
                
                
                <category>Cloud Native</category>
                
            </item>
        
            <item>
                <title>MBA Graduation: With Distinction, Israel Ogbole</title>
                <description>&lt;p&gt;I am super stoked. I attended my graduation with family and friends, and I am especially proud that my kids were present. The moment was surreal, surrounded by the people who supported me throughout this journey.&lt;/p&gt;

&lt;p&gt;Needless to say, doing an MBA whilst working full-time and a young family wasn’t exactly easy. Balancing work responsibilities, family time, and the demands of the MBA program required a lot of dedication and sacrifice. Late nights, early mornings, and countless weekends were spent studying and completing assignments. But then again, nothing good comes easy in life.&lt;/p&gt;

&lt;p&gt;Despite the challenges, the journey was incredibly rewarding. I learned so much, not only from the courses but also from the diverse experiences and perspectives of my classmates. The skills and knowledge I gained have already started to pay off in my professional life, and I am excited about the new opportunities that lie ahead.&lt;/p&gt;

&lt;p&gt;Here’s a glimpse of the ceremony, a moment I will cherish forever:&lt;/p&gt;

&lt;p&gt;It was worth it!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.licdn.com/dms/image/D4E22AQE3-sBFEBQIgA/feedshare-shrink_1280/0/1706012211197?e=1724889600&amp;amp;v=beta&amp;amp;t=rJh50RM-uL3wSUd8SvVC5ZRiDWxX_LWHbms39ZK2Gj0&quot; alt=&quot;Certificate&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/676e821c-55d8-4747-aaa1-f162bad904b7#wide&quot; alt=&quot;Graduation&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
</description>
                <pubDate>Fri, 28 Jun 2024 12:01:35 +0000</pubDate>
                <link>https://israelo.io/blog/mba-grad/</link>
                <guid isPermaLink="true">https://israelo.io/blog/mba-grad/</guid>
                
                <category>personal</category>
                
                
                <category>Personal</category>
                
            </item>
        
            <item>
                <title>KubeCon Paris: Highlights and Key Trends</title>
                <description>&lt;p&gt;Fantastic week at #KubeCon Paris.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key trends:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The user of AI/GPU demoninated the keynotes&lt;/li&gt;
  &lt;li&gt;OpenTelemetry - The adoption of continuous profiling.  I am super excited about the role  I played in making this happen&lt;/li&gt;
  &lt;li&gt;WebAssembly - it’s potential to enhance application portability&lt;/li&gt;
  &lt;li&gt;Environmental Sustainability, and&lt;/li&gt;
  &lt;li&gt;eBPF for observability and security use cases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It was amazing to reconnect with industry peers, meet new people, and dive deep into cloud-native advancements.&lt;/p&gt;

&lt;p&gt;Even more exciting was sharing my passion for continuous profiling, its adoption in OpenTelemetry, and Elastic’s contribution to this progress.&lt;/p&gt;

&lt;p&gt;My favorite talk was by &lt;strong&gt;John Fastabend and Liz Rice&lt;/strong&gt; on eBPF’s limitations. While familiar with eBPF’s capabilities, I, like many other attendees, was particularly curious to hear their thoughts on its limitations. After all, who better to critique eBPF than the experts who practically wrote it?&lt;/p&gt;

&lt;p&gt;Their talk exceeded expectations, including a crash course on Turing completeness and a live demo of Conway’s Game of Life – using eBPF!&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/tClsqnZMN6I?si=i6wg8apuFvdIaZP1&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;blockquote&gt;
  &lt;p&gt;I had to take a selfie; my daughter would never forgive me otherwise! “Dad, are you watching Liz’s coding video again?” 😂&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Join the conversation on &lt;a href=&quot;https://www.linkedin.com/posts/israelo_ebpf-activity-7178699786080919552-TQmc&quot;&gt;LinkedIn&lt;/a&gt;&lt;/em&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/8dc3c87b-b4b7-4844-841f-ae75ab6325c4&quot; alt=&quot;LinkedIn&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;in-pictures&quot;&gt;In pictures&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/b978b546-ef17-4103-abee-f0ee9ccc4c77&quot; alt=&quot;1711489957314&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/47bf21ed-6429-4d3b-b164-abe8101fb429&quot; alt=&quot;1711489957507&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/48c2f625-7aec-41a3-baab-b04bab2ace95&quot; alt=&quot;1711364186230&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/90b4ac7c-51df-4c03-a2ed-6dd18234fe46&quot; alt=&quot;1711364177834&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/c0a8fd28-25f0-428c-a622-e7d99ac33b05&quot; alt=&quot;1711364177350&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/fc45b695-c48a-426b-8c03-565796d93689&quot; alt=&quot;1711364179839&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/c8af050e-39bb-4903-b296-9e17e4a0d7ea&quot; alt=&quot;1711364179742&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/4fc51f45-69f0-47af-8c34-50a98d2e58b6&quot; alt=&quot;1711364186496&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/4f5af8fe-365e-4d9d-bd93-fb96b36b09d6&quot; alt=&quot;1711364177895&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That’s it!&lt;/p&gt;
</description>
                <pubDate>Thu, 28 Mar 2024 12:01:35 +0000</pubDate>
                <link>https://israelo.io/blog/kubecon-paris/</link>
                <guid isPermaLink="true">https://israelo.io/blog/kubecon-paris/</guid>
                
                <category>containers</category>
                
                <category>devops</category>
                
                <category>cloud-native</category>
                
                <category>kubernetes</category>
                
                <category>ebpf</category>
                
                
                <category>Cloud Native</category>
                
            </item>
        
            <item>
                <title>BLUF: A Key to Effective Communication for Product Managers</title>
                <description>&lt;p&gt;&lt;strong&gt;BLUF:&lt;/strong&gt; For product managers, adopting the Bottom Line Up Front (BLUF) communication technique can drastically improve clarity and efficiency in messaging, ensuring critical information is immediately clear and actionable.&lt;/p&gt;

&lt;p&gt;In the fast-paced world of product management, clear and concise communication is not just a skill—it’s an imperative. One method stands out for its ability to cut through noise and drive home the core message right from the start: BLUF, or &lt;strong&gt;Bottom Line Up Front&lt;/strong&gt;. This approach, with its origins in the military, offers a blueprint for communication that product managers can leverage to enhance clarity, decision-making, and efficiency in their teams. Let’s dive into what BLUF is, its military roots, why it’s invaluable for product managers, and how it differs from the commonly known TL;DR.&lt;/p&gt;

&lt;h2 id=&quot;what-is-bluf&quot;&gt;What is BLUF?&lt;/h2&gt;

&lt;p&gt;BLUF is a communication technique that presents the conclusion or the most important information at the beginning of the message. Instead of building up to the main point through background information or a narrative, BLUF demands that you start with the main message. This method ensures that the recipient understands the essence of the message immediately, enabling faster comprehension and action.&lt;/p&gt;

&lt;p&gt;The essence of BLUF lies in its simplicity and directness. It challenges the communicator to distil their message to its core, thereby respecting the recipient’s time and cognitive load. In doing so, BLUF not only facilitates faster comprehension but also encourages a more focused and action-oriented dialogue.&lt;/p&gt;

&lt;h3 id=&quot;example-product-launch-briefing&quot;&gt;Example: Product Launch Briefing&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Without BLUF:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A meeting that starts with a review of the product development process, a detailed description of the product features, and gradually leads to the launch strategy and expected outcomes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With BLUF:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;” &lt;strong&gt;Bottom Line Up Front:&lt;/strong&gt; Our new product will launch on March 15, targeting the young adult demographic with its innovative features designed to enhance their digital lifestyle. Our strategy focuses on digital marketing campaigns and strategic partnerships to maximize reach and engagement.&lt;/p&gt;

&lt;p&gt;Now, let’s dive into how we got here, the product’s unique selling points, and the detailed launch plan to ensure we’re all aligned and ready to make this launch a success.”&lt;/p&gt;

&lt;p&gt;In this briefing, the BLUF method ensures that the team immediately understands the what, when, and who of the product launch, setting the stage for a more detailed discussion on strategy and execution.&lt;/p&gt;

&lt;h2 id=&quot;origin-in-the-military&quot;&gt;Origin in the Military&lt;/h2&gt;

&lt;p&gt;The BLUF technique has its roots in the military, where clear, concise communication can be the difference between success and failure, or even life and death. In this context, the ability to convey critical information swiftly and unmistakably is paramount. The military environment, characterized by the need for rapid decision-making under pressure, has thus championed the BLUF approach to ensure that essential information is never buried or overlooked.&lt;/p&gt;

&lt;h2 id=&quot;why-product-managers-should-use-bluf&quot;&gt;Why Product Managers Should Use BLUF&lt;/h2&gt;

&lt;p&gt;In the world of product management, time is a precious commodity, and ambiguity is the enemy. Here’s why the BLUF approach is particularly well-suited for product managers:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Enhances Clarity:&lt;/strong&gt; By stating the conclusion or main point upfront, BLUF eliminates the risk of key details getting lost in the shuffle. This clarity is crucial when communicating with stakeholders, team members, and customers who rely on precise information to make informed decisions.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Saves Time:&lt;/strong&gt; In an era where everyone is battling information overload, BLUF respects the recipient’s time. It allows readers to quickly grasp the message’s essence without sifting through extraneous details.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Facilitates Decision Making:&lt;/strong&gt; Product managers often need to drive or facilitate decision-making processes. BLUF communication ensures that the decision-makers have the critical information they need from the get-go, enabling more efficient and effective decisions.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Improves Email Efficiency:&lt;/strong&gt; In a digital age where emails are a primary mode of communication, adopting a BLUF approach can significantly increase the efficiency of email correspondence, ensuring that the most important messages are seen and understood quickly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;bluf-vs-tldr&quot;&gt;BLUF vs. TL;DR&lt;/h2&gt;

&lt;p&gt;While BLUF and TL;DR (Too Long; Didn’t Read) both aim to summarize content, they serve different purposes and contexts. TL;DR is typically used at the end of a lengthy text to offer a brief summary for those who may not have the time or inclination to read the full text. In contrast, BLUF places the summary or conclusion at the beginning, ensuring that the reader is immediately aware of the main point before delving into any further details.&lt;/p&gt;

&lt;p&gt;This distinction makes BLUF particularly effective for professional and strategic communications where immediate comprehension is critical, whereas TL;DR serves as a courtesy to provide a snapshot of lengthy digital content for casual readers.&lt;/p&gt;

&lt;h2 id=&quot;in-conclusion&quot;&gt;In Conclusion&lt;/h2&gt;

&lt;p&gt;For product managers looking to streamline communication and enhance decision-making within their teams and projects, adopting the BLUF approach can be a game-changer. By bringing the bottom line up front, you not only respect your audience’s time but also ensure that your message’s core is never missed. In the demanding field of product management, mastering the art of BLUF communication could very well be the key to efficiency, clarity, and success.&lt;/p&gt;

&lt;p&gt;As the digital workspace continues to evolve, embracing techniques like BLUF will be essential for professionals looking to maintain a competitive edge through superior communication strategies. So, the next time you draft an email or prepare a presentation, remember the power of starting with the bottom line up front. Your team, stakeholders, and inbox will thank you.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;BLUF: The Military Standard That Can Make Your Writing More Powerful&lt;/strong&gt; - 
&lt;a href=&quot;https://www.animalz.co/blog/bluf-the-military-standard/&quot;&gt;Ref&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;BLUF Meaning: Learn How to Write Better with This Technique&lt;/strong&gt; 
&lt;a href=&quot;https://rockcontent.com/blog/bluf-meaning/&quot;&gt;Ref&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;
</description>
                <pubDate>Fri, 23 Feb 2024 12:01:35 +0000</pubDate>
                <link>https://israelo.io/blog/bluf/</link>
                <guid isPermaLink="true">https://israelo.io/blog/bluf/</guid>
                
                <category>product</category>
                
                <category>personal</category>
                
                
                <category>Product</category>
                
            </item>
        
    </channel>
</rss>