<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: CharmPic</title>
    <description>The latest articles on DEV Community by CharmPic (@charmpic).</description>
    <link>https://dev.to/charmpic</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3301778%2Fb25090e0-32de-44a7-a2b3-8691c3a7f56a.png</url>
      <title>DEV Community: CharmPic</title>
      <link>https://dev.to/charmpic</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/charmpic"/>
    <language>en</language>
    <item>
      <title>I rebuilt the "Simple Web Server" from 20 years ago.</title>
      <dc:creator>CharmPic</dc:creator>
      <pubDate>Thu, 20 Aug 2026 04:14:59 +0000</pubDate>
      <link>https://dev.to/charmpic/i-rebuilt-the-simple-web-server-from-20-years-ago-15a2</link>
      <guid>https://dev.to/charmpic/i-rebuilt-the-simple-web-server-from-20-years-ago-15a2</guid>
      <description>&lt;p&gt;20 Years Ago, I Built a Simple Web Server by Reading HTTP Specs. Today, I Rebuilt It with Modern .NET and AI.&lt;br&gt;
Back in 2005, I read through HTTP protocol books and painstakingly hand-crafted a lightweight Windows utility called "Easy Web Server" (簡単WEBサーバー).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpdq2borafrhct35a1c9s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpdq2borafrhct35a1c9s.png" alt=" " width="800" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fast-forward about 20 years: instead of wrestling with low-level socket boilerplate, we now have powerful standard libraries—and AI collaborators to bounce ideas off of. So, I decided to completely rewrite the tool from scratch as EasyHTTPServer 2.&lt;/p&gt;

&lt;p&gt;Rather than patching 20-year-old legacy code, this is a clean-slate implementation powered by C# / .NET 10, ASP.NET Core Kestrel, and WPF.&lt;/p&gt;

&lt;p&gt;Key Features&lt;/p&gt;

&lt;p&gt;One-Click File Sharing: Select a folder and start a read-only HTTP file server instantly.&lt;/p&gt;

&lt;p&gt;Static Site Hosting: Host simple static websites with index.html support.&lt;/p&gt;

&lt;p&gt;Flexible Binding: Works on localhost, Home LAN, and VPN environments.&lt;/p&gt;

&lt;p&gt;Zero-Config LAN HTTPS &amp;amp; Pairing: Built-in HTTPS with a quick-pairing mechanism for secure local network sharing.&lt;/p&gt;

&lt;p&gt;Large File &amp;amp; Resume Support: Handles large downloads with HTTP range requests (resume capability).&lt;/p&gt;

&lt;p&gt;Classic 2005 Theme: A nostalgic UI skin that pays homage to the original 2005 release.&lt;/p&gt;

&lt;p&gt;The original tool holds a special place in my heart, having been used in school classrooms for introductory HTML lessons back in the day. While preserving its signature "just works" simplicity, the architecture has been thoroughly modernized to eliminate old risks—such as path traversal vulnerabilities and unsafe CGI execution.&lt;/p&gt;

&lt;p&gt;Getting Started (Windows x64)&lt;br&gt;
Simply extract the ZIP package and launch EasyHTTPServer.exe—no complicated setup required.&lt;/p&gt;

&lt;p&gt;GitHub Repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/moe-charm/EasyHTTPServer" rel="noopener noreferrer"&gt;https://github.com/moe-charm/EasyHTTPServer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Windows Download (Alpha Release):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/moe-charm/EasyHTTPServer/releases/tag/v2.0.0-alpha.1" rel="noopener noreferrer"&gt;https://github.com/moe-charm/EasyHTTPServer/releases/tag/v2.0.0-alpha.1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is currently in alpha, but I plan to iteratively refine it—striking the right balance between 2000s nostalgia and modern security standards. Feedback and contributions are warmly welcome!&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>chatgpt</category>
    </item>
    <item>
      <title>Building a Binaural VST and Why I Couldn't Get 'Elevation' Right</title>
      <dc:creator>CharmPic</dc:creator>
      <pubDate>Sun, 02 Aug 2026 17:21:39 +0000</pubDate>
      <link>https://dev.to/charmpic/building-a-binaural-vst-and-why-i-couldnt-get-elevation-right-1361</link>
      <guid>https://dev.to/charmpic/building-a-binaural-vst-and-why-i-couldnt-get-elevation-right-1361</guid>
      <description>&lt;p&gt;Since my beloved dearVR was end-of-lifed, I built this in collaboration with GPT-5.6-Sol, with Opus 5 writing the main draft of this article.&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;NekoSpace Binaural&lt;/strong&gt;, a spatialization VST plugin designed for audio dramas and ASMR, and recently released the first alpha.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/moe-charm/nekospace-audio" rel="noopener noreferrer"&gt;https://github.com/moe-charm/nekospace-audio&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Release:&lt;/strong&gt; &lt;a href="https://github.com/moe-charm/nekospace-audio/releases/tag/v0.1.0-alpha" rel="noopener noreferrer"&gt;https://github.com/moe-charm/nekospace-audio/releases/tag/v0.1.0-alpha&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tech Stack:&lt;/strong&gt; C++17 / JUCE 9.0.0 / CMake, AGPLv3, Windows VST3 + Standalone&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article isn't a celebratory "look what I built" post. Instead, its purpose is to &lt;strong&gt;document what worked and what didn't, backed by real numbers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In particular, my four attempts at handling "elevation" (vertical localization) failed to yield a decisive result. I believe documenting that failure is where the real value lies, so I’ve dedicated most of this post to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Build It?
&lt;/h2&gt;

&lt;p&gt;Normally, I record using a Neumann KU100 dummy head microphone. While the KU100 captures the actual acoustic space beautifully, there are always cases where you need to &lt;strong&gt;place a mono source at an arbitrary position during post-production&lt;/strong&gt;—such as sound effects, added dialogue, or whisperings right next to the listener's ear. Existing plugins are mostly built for games/VR, and they lack convincing proximity expressions for placing a voice "right by the ear." That was the starting point.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; Naturally, &lt;strong&gt;you should never run materials already recorded with a KU100 through this plugin&lt;/strong&gt;, as that would apply head-related transfer functions twice. The target input is strictly dry mono/stereo material.&lt;/p&gt;




&lt;h1&gt;
  
  
  What Worked
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Computing ITD from Exact Ray Paths on a Rigid Sphere
&lt;/h2&gt;

&lt;p&gt;Instead of deriving Interaural Time Difference (ITD) from the measurement delays embedded in HRIRs, I designed the system to &lt;strong&gt;calculate ITD geometrically on every frame&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Since the ears lie on the surface of a sphere, there are two ray paths from the sound source to the ear: a straight line when the ear is visible, and &lt;strong&gt;a tangent + a great-circle arc&lt;/strong&gt; when the ear falls into the acoustic shadow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The ear is "on" the sphere. Line-of-sight exists when the sound source &lt;/span&gt;
&lt;span class="c1"&gt;// is outside the ear's tangent plane: r * cos(theta) &amp;gt;= a &amp;lt;=&amp;gt; theta &amp;lt;= acos(a/r)&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;thetaVis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;acos&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clampf&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;theta&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;thetaVis&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sourcePos&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;earPos&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;           &lt;span class="c1"&gt;// Straight line&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;tangent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;sqrt&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;max&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;tangent&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;theta&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;thetaVis&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;           &lt;span class="c1"&gt;// Tangent + arc&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The main benefit of this approach is that &lt;strong&gt;proximity exaggeration emerges naturally from the geometry&lt;/strong&gt;, without artificial tuning. At a distance of 12 cm directly to the side, the Interaural Level Difference (ILD) widens up to &lt;strong&gt;24.2 dB&lt;/strong&gt;. In contrast, standard far-field approximations (like Woodworth's formula) yield only &lt;strong&gt;5.6 dB&lt;/strong&gt;. The plugin’s &lt;code&gt;NEAR FIELD&lt;/code&gt; knob continuously blends between these two models: 0% acts as a standard panner, while 100% applies full per-ear geometry.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Bug I Ran Into
&lt;/h3&gt;

&lt;p&gt;Initially, I wrote the visibility boundary condition as &lt;code&gt;π/2 + acos(a/r)&lt;/code&gt;. A code review pointed out the mistake.&lt;/p&gt;

&lt;p&gt;The correct boundary is simply &lt;code&gt;acos(a/r)&lt;/code&gt;. At this boundary, &lt;code&gt;|S - E| == sqrt(r² - a²)&lt;/code&gt; (matching the tangent length), making the two conditional branches connect continuously. With the incorrect boundary, the transition into the acoustic shadow occurred at the wrong angle, causing &lt;strong&gt;the ITD to jump discontinuously near 90° azimuth&lt;/strong&gt;. This manifested as audible clicks/pops when panning.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Lesson learned:&lt;/em&gt; Whenever geometry can be written in closed form, always write unit tests to verify boundary continuity.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Late-Only Voice Ducking
&lt;/h2&gt;

&lt;p&gt;A common requirement in audio drama production is: &lt;em&gt;"I want to add reverb, but I can't let it mud up the vocal clarity."&lt;/em&gt; The typical workaround is manually writing reverb send automations, which is tedious and often sounds unnatural.&lt;/p&gt;

&lt;p&gt;I implemented a ducking feature that &lt;strong&gt;attenuates only the late reverberation while the voice is actively playing&lt;/strong&gt;. Three specific design decisions made this effective:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(a) Duck the FDN output, NOT the input.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is key. If you attenuate at the input, the reverb energy never builds up inside the network, causing the reverb to "start growing" the moment the voice stops. By suppressing at the output, &lt;strong&gt;the reverb energy accumulated inside naturally emerges at the end of a phrase&lt;/strong&gt;. The room reflection rises exactly at the end of the spoken line as intended.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(b) Do not touch direct sound or early reflections.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Early reflections carry the spatial "shape" of the room. Furthermore, as described later, they are rendered through HRTFs for each image direction, serving as part of the height cues. Only the late reverb muddies the voice, so that's all we duck.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(c) Make it threshold-less.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;envAtt&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;envRel&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;refRel&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// Reference level decaying over seconds&lt;/span&gt;

&lt;span class="c1"&gt;// Relative to "recent input level", independent of input gain or speaking style&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;activity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clampf&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kActivityFraction&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;depth&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;activity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;gain&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;duckAtt&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;duckRel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Fast duck, slow recovery&lt;/span&gt;
&lt;span class="n"&gt;gain&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;gain&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ref&lt;/code&gt; is a slowly decaying baseline level. By evaluating activity relative to this baseline, &lt;strong&gt;the ducking behaves consistently whether the input is a soft whisper or a loud shout&lt;/strong&gt;. This eliminated the need for a dB threshold knob on the UI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Measurement:&lt;/strong&gt; Isolating the room bus (subtracting the dry rendering), the reverb level dropped to &lt;strong&gt;−13.1 dB&lt;/strong&gt; during speech and returned to &lt;strong&gt;−0.07 dB&lt;/strong&gt; post-speech.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Note: Initially, I measured the total output and panicked because it only showed a −1.6 dB drop. Since the direct sound dominates the output, that was expected—I had simply measured at the wrong tap point! Always isolate the target bus when measuring DSP effects.)&lt;/em&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  What Didn't Work: Elevation
&lt;/h1&gt;

&lt;p&gt;Here is the core of the problem. &lt;strong&gt;Across four iterations, vertical localization never reached a level where a listener could confidently say, "That sound is coming from above."&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Round 1: Rebuilding the Analytical Pinna Model
&lt;/h2&gt;

&lt;p&gt;I modeled pinna notch filters by sweeping the notch frequency from 4.2 kHz to 11.5 kHz based on elevation, adding companion peaks and a high-frequency shelf.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Spectral difference (4–14 kHz, top vs. bottom):&lt;/strong&gt; Expanded from &lt;strong&gt;2.0 dB → 5.8 dB&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Perceptual outcome:&lt;/strong&gt; Tonal timber clearly changed. Vertical positioning remained completely unperceivable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Round 2: Empirical HRTF (Neumann KU100)
&lt;/h2&gt;

&lt;p&gt;Hypothesizing that the analytical model was too crude, I integrated measured KU100 HRTF data from TH Köln (Bernschütz 2013, Lebedev 2702 grid points, CC BY-SA).&lt;/p&gt;

&lt;p&gt;Key steps during dataset conversion:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Removed dataset ITD:&lt;/strong&gt; Since the engine calculates ITD geometrically, leaving measurement delays in the HRIRs caused double delay. I minimum-phased the response via real-cepsrum unwrapping to strip group delay while preserving magnitude responses. Truncating to 256 taps remained clean because energy was concentrated at the head.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verified coordinate system &amp;amp; symmetry:&lt;/strong&gt; SOFA &lt;code&gt;SimpleFreeFieldHRIR&lt;/code&gt; uses counter-clockwise positive angles (left is positive), whereas my engine uses right-positive. I verified with tests that an &lt;code&gt;az +90°&lt;/code&gt; source produced higher levels in the right ear.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Normalized frontal level:&lt;/strong&gt; Vital to ensure listening tests compared spectral shape rather than sheer volume differences.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Spectral difference (4–14 kHz):&lt;/strong&gt; &lt;strong&gt;6.4 dB&lt;/strong&gt; (wider than Analytical Model B's 5.8 dB).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Perceptual outcome:&lt;/strong&gt; &lt;strong&gt;Indistinguishable from Analytical B.&lt;/strong&gt; Vertical position was still imperceptible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Despite the dataset showing larger numerical spectral differences, perceived spatialization didn't change. This ruled out the hypothesis that "just swapping the dataset will fix it."&lt;/p&gt;

&lt;h2&gt;
  
  
  Round 3: Pinna-Independent Elevation Cues
&lt;/h2&gt;

&lt;p&gt;If fine spectral pinna notches depend heavily on &lt;strong&gt;the listener's own pinna shape&lt;/strong&gt;, I reasoned that adding pinna-independent cues might help.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(a) Rendering Early Reflections through HRTFs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Previously, early reflections used equal-power panning. This was a flaw: &lt;code&gt;atan2(x, z)&lt;/code&gt; yields &lt;strong&gt;identical panning gains for sound sources above vs. below&lt;/strong&gt;. The reflections carried zero directional information. By routing each mirror image reflection through HRTFs based on its actual arrival angle, overhead sounds finally received floor reflections coming from below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Room response difference (top vs. bottom):&lt;/strong&gt; &lt;strong&gt;5.9 dB&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;(b) Modeling Torso / Shoulder Reflections&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I added a comb filter notch between 440 Hz–1.2 kHz that moves with elevation. Because it operates in lower frequencies, it is less affected by headphone coloration.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Low-frequency difference (0.7–3 kHz):&lt;/strong&gt; Analytical A = &lt;strong&gt;0.11 dB&lt;/strong&gt;, Analytical B = &lt;strong&gt;2.15 dB&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;(Note: The KU100 dummy head lacks a torso, so it inherently lacks these shoulder reflection cues—likely one reason the empirical dataset didn't outperform analytical models in Round 2.)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Perceptual outcome:&lt;/strong&gt; Still weak.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Round 4: Manual Per-Listener Tuning (Elevation Lab)
&lt;/h2&gt;

&lt;p&gt;I abandoned expanding generic models and shifted toward a &lt;strong&gt;listener-tuned manual calibration system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I created three elevation anchors (&lt;code&gt;Below −60°&lt;/code&gt;, &lt;code&gt;Level 0°&lt;/code&gt;, &lt;code&gt;Above +60°&lt;/code&gt;), each holding 8 parameters: notch frequency, depth, Q, companion peak ratio, HF shelf, and torso delay/gain. Intermediate angles are interpolated; angles beyond ±60° are extrapolated.&lt;/p&gt;

&lt;p&gt;Anchors allowed &lt;strong&gt;independent tuning of top and bottom responses&lt;/strong&gt;. In Analytical B, all parameters were derived from &lt;code&gt;sin/cos&lt;/code&gt; of elevation, meaning tweaking "Above" invariably distorted "Below".&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Verified via unit test: Shifting the &lt;code&gt;Above&lt;/code&gt; notch anchor from 9.7 kHz → 14 kHz moved the rendered top notch to 13.4 kHz while the &lt;code&gt;Below&lt;/code&gt; notch remained &lt;strong&gt;strictly fixed at 4850 Hz&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, surfacing 24 raw parameters in the UI was &lt;strong&gt;completely unusable&lt;/strong&gt;. It was mathematically sound, but terrible for real-time ears-on tweaking. I collapsed them into 4 macro controls: &lt;code&gt;UP&lt;/code&gt;, &lt;code&gt;DOWN&lt;/code&gt;, &lt;code&gt;BODY&lt;/code&gt;, and &lt;code&gt;FOCUS&lt;/code&gt;, hiding raw controls inside an &lt;code&gt;Advanced&lt;/code&gt; foldout. At macro value 1.00, it bit-accurately reproduces Analytical B, ensuring "Reset" actually means Reset.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Perceptual outcome:&lt;/strong&gt; &lt;em&gt;"There was a slight sense of vertical motion, but still nowhere near a convincing 'above' localization."&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It was better than Round 3—there was a sense of directional movement—but calling it "above" would be dishonest.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion &amp;amp; Key Takeaways
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Analytic A&lt;/th&gt;
&lt;th&gt;Analytic B&lt;/th&gt;
&lt;th&gt;KU100 Measured&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Upper Spectral Diff (4–14 kHz)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2.0 dB&lt;/td&gt;
&lt;td&gt;5.8 dB&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6.4 dB&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lower Spectral Diff (0.7–3 kHz)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.11 dB&lt;/td&gt;
&lt;td&gt;2.15 dB&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ILD at az +90°&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;12.7 dB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;All four approaches improved the numerical metrics. None achieved convincing vertical perception.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I concluded that this is not an implementation bug, but &lt;strong&gt;the known ceiling of static, non-personalized binaural audio&lt;/strong&gt;. The reasons are clear:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Spectral elevation cues depend heavily on &lt;strong&gt;the unique physical shape of the listener's own ears&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Headphones heavily &lt;strong&gt;disrupt/re-color that exact 5–12 kHz frequency region&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The most powerful elevation cue—&lt;strong&gt;head tracking—is structurally impossible here&lt;/strong&gt;, as audio dramas are distributed as pre-rendered static audio files.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Consequently, I decided to &lt;strong&gt;release the plugin while explicitly stating in the README that elevation cues are weak&lt;/strong&gt;. The feature remains in the DSP pipeline, but I will not market it as a reliable localization tool. In voice productions, conveying height is far more reliably achieved through script design, footsteps, and spatial reverb—which is how traditional radio dramas have handled it for decades.&lt;/p&gt;

&lt;p&gt;I committed all failed experiments and numerical findings directly into the public repository as &lt;a href="https://github.com/moe-charm/nekospace-audio/blob/main/plugins/binaural/docs/elevation-findings.md" rel="noopener noreferrer"&gt;&lt;code&gt;elevation-findings.md&lt;/code&gt;&lt;/a&gt;. Negative results are worth preserving.&lt;/p&gt;




&lt;h1&gt;
  
  
  DSP &amp;amp; Architecture Lessons
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Choice Lists (Enums) Must Be Frozen Before Release
&lt;/h2&gt;

&lt;p&gt;Deciding this upfront saved the project.&lt;/p&gt;

&lt;p&gt;Plugin state management (like JUCE's APVTS) saves choice parameters using &lt;strong&gt;denormalized indices&lt;/strong&gt;, so appending options to the end of a list later won't break existing project files. Adding persistent string keys (e.g., &lt;code&gt;analytic_b&lt;/code&gt;) ensures safety across display name changes or localizations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The real hazard is host automation.&lt;/strong&gt; VST3/AU automations save values normalized as &lt;code&gt;index / (count - 1)&lt;/code&gt;. The moment you add an option to an enum, &lt;code&gt;count&lt;/code&gt; changes, causing &lt;strong&gt;all past host automations to point to the wrong option&lt;/strong&gt;. This cannot be rescued by plugin state formats alone.&lt;/p&gt;

&lt;p&gt;My rule: &lt;em&gt;If you want to add options after release, create a new parameter ID.&lt;/em&gt; I explicitly marked frozen IDs in the CHANGELOG. This is why 4 HRTF profiles (including one dev-only profile) were reserved from day one.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Self-correction note: I previously misspoke on this, asserting APVTS broke saved states. In reality, APVTS saves denormalized indices safely; it's the host automation mapping that breaks. Don't guess format behaviors—read the code!)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Keep the DSP Core Independent of JUCE
&lt;/h2&gt;

&lt;p&gt;I enforced an architectural rule: &lt;code&gt;src/dsp&lt;/code&gt; must never &lt;code&gt;#include &amp;lt;JuceHeader.h&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Because of this, &lt;strong&gt;30 acceptance tests run without instantiating a plugin wrapper&lt;/strong&gt;. Builds and test executions complete in milliseconds, and CI failures can be pinpointed instantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Don't Trust CI Until You See It Fail (and Pass)
&lt;/h2&gt;

&lt;p&gt;A Git tag triggers GitHub Actions to run &lt;code&gt;configure&lt;/code&gt; → &lt;code&gt;build&lt;/code&gt; → &lt;strong&gt;&lt;code&gt;test&lt;/code&gt;&lt;/strong&gt; → &lt;code&gt;package&lt;/code&gt; → &lt;code&gt;publish&lt;/code&gt;, generating a draft release. If tests fail, the workflow halts.&lt;/p&gt;

&lt;p&gt;However, this failed me once: I added CI but didn't monitor its real run. A runner mismatch (&lt;code&gt;windows-latest&lt;/code&gt; dropping VS 2022 components) broke CI on every push without me noticing. Pinning to &lt;code&gt;windows-2022&lt;/code&gt; fixed it. &lt;strong&gt;CI implementation isn't done when you commit the file; it's done when you watch it turn green.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Geometric ITD, proximity modeling, and late-only ducking worked as intended.&lt;/li&gt;
&lt;li&gt;Elevation failed perceptually across 4 iterations despite solid numerical improvements. I accepted this as &lt;strong&gt;a fundamental ceiling of static binaural audio&lt;/strong&gt; and documented it in the README.&lt;/li&gt;
&lt;li&gt;Freeze irreversible contracts (parameter IDs, choice lists) &lt;strong&gt;before&lt;/strong&gt; v1 release.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As an alpha release, there is still room to polish the sound. It's available as Windows VST3 + Standalone under the AGPLv3 license. If you're interested, feel free to give it a spin—&lt;strong&gt;headphones are required!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/moe-charm/nekospace-audio" rel="noopener noreferrer"&gt;https://github.com/moe-charm/nekospace-audio&lt;/a&gt;&lt;/p&gt;

</description>
      <category>chatgpt</category>
      <category>claude</category>
    </item>
    <item>
      <title>What I Learned Building 12 Generations of Memory Allocators: Balancing Speed and Low RSS</title>
      <dc:creator>CharmPic</dc:creator>
      <pubDate>Tue, 14 Jul 2026 23:57:58 +0000</pubDate>
      <link>https://dev.to/charmpic/what-i-learned-building-12-generations-of-memory-allocators-balancing-speed-and-low-rss-210a</link>
      <guid>https://dev.to/charmpic/what-i-learned-building-12-generations-of-memory-allocators-balancing-speed-and-low-rss-210a</guid>
      <description>&lt;p&gt;My personal research project, the &lt;strong&gt;Hakozuna&lt;/strong&gt; memory allocator, has recently reached its 12th generation (HZ12).&lt;/p&gt;

&lt;p&gt;Even though it doesn't make me a single dime, I somehow ended up building 12 different generations.&lt;br&gt;
This time, I have published a paper on Zenodo that synthesizes the findings and designs of HZ10, HZ11, and HZ12.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Paper (Zenodo):&lt;/strong&gt; &lt;a href="https://doi.org/10.5281/zenodo.21360690" rel="noopener noreferrer"&gt;https://doi.org/10.5281/zenodo.21360690&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/hakorune/hakozuna" rel="noopener noreferrer"&gt;https://github.com/hakorune/hakozuna&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note: The Zenodo repository includes PDFs of both the English and Japanese versions of the paper.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  What is Hakozuna?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Hakozuna&lt;/strong&gt; is a family of memory allocators I developed to research various aspects of memory management, including &lt;code&gt;malloc&lt;/code&gt;/&lt;code&gt;free&lt;/code&gt; performance, RSS (Resident Set Size), remote free operations, and safety.&lt;/p&gt;

&lt;p&gt;Each generation has a specific focus:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Generation&lt;/th&gt;
&lt;th&gt;Key Theme&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HZ3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High-speed local-heavy allocation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HZ4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Remote-free / message-passing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HZ5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Descriptor-owned, low RSS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HZ6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fail-closed route contracts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HZ8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Balanced allocator for general-purpose use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HZ10&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Route, lifecycle, and measurement boundaries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HZ11&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ownerless, speed-first recycling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HZ12&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Advisory ownership and bounded span reclamation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Currently, &lt;strong&gt;HZ8&lt;/strong&gt; is the recommended default allocator for general use.&lt;br&gt;
On the other hand, the &lt;strong&gt;HZ10–HZ12&lt;/strong&gt; series represents a more research-oriented branch.&lt;/p&gt;


&lt;h2&gt;
  
  
  HZ11: Prioritizing a Fast Recycling Path
&lt;/h2&gt;

&lt;p&gt;In HZ11, we explicitly avoided the design where the thread freeing an object must return it to its original owner thread on every single &lt;code&gt;free&lt;/code&gt; call.&lt;/p&gt;

&lt;p&gt;Instead, we introduced the following structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;front cache ──&amp;gt; transfer cache ──&amp;gt; central spans ──&amp;gt; ownerless recycling

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

&lt;/div&gt;



&lt;p&gt;By avoiding ownership checks during every &lt;code&gt;free&lt;/code&gt; operation, we can significantly shorten the hot path.&lt;/p&gt;

&lt;p&gt;In our remote/mixed benchmarks on Linux x86-64, &lt;strong&gt;HZ11 fine128&lt;/strong&gt; achieved the following throughput ratios compared to &lt;strong&gt;tcmalloc&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workload&lt;/th&gt;
&lt;th&gt;HZ11 / tcmalloc Throughput Ratio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;main_r50&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1.853x&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;main_r90&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2.346x&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;medium_r50&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4.590x&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;medium_r90&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6.097x&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Disclaimer:&lt;/strong&gt; These results are highly specific to certain benchmarks, machines, and lanes. This does not imply that HZ11 is universally faster than tcmalloc.&lt;br&gt;
For instance, in the Windows &lt;code&gt;broad-MT balanced&lt;/code&gt; benchmark, HZ11 reached about 422M ops/s, which is roughly 81.7% of tcmalloc's performance. However, in &lt;code&gt;larger_sizes&lt;/code&gt;, it achieved around 149%. There are very clear strengths and weaknesses.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The Weakness of Ownerless Recycling
&lt;/h3&gt;

&lt;p&gt;While ownerless recycling is incredibly fast, it introduces a major challenge: when objects are scattered across multiple threads' caches or central structures, it becomes extremely difficult to determine if a specific span has become completely empty.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fast recycling of objects 
   └── BUT ──&amp;gt; Hard to safely decommit entire spans

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

&lt;/div&gt;



&lt;p&gt;Adding atomic counters or owner lookups to every &lt;code&gt;free&lt;/code&gt; call would make tracking empty spans easier, but it increases the fixed overhead of &lt;code&gt;malloc&lt;/code&gt; and &lt;code&gt;free&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This trade-off is what led to the design shift in &lt;strong&gt;HZ12&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  HZ12: Decoupling Ownership from Safety Guarantees
&lt;/h2&gt;

&lt;p&gt;In HZ12, the &lt;strong&gt;ownership tag&lt;/strong&gt; is no longer treated as the ultimate authority that guarantees the safety of a reclaim operation. Instead, it serves merely as a &lt;strong&gt;hint&lt;/strong&gt; to find candidates.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ownership token:&lt;/strong&gt; A hint to narrow down candidate searches.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reclaim authority:&lt;/strong&gt; Decided by verifying multiple conditions on the cold path:&lt;/li&gt;
&lt;li&gt;Complete-span snapshot&lt;/li&gt;
&lt;li&gt;Inbox emptiness&lt;/li&gt;
&lt;li&gt;State validation&lt;/li&gt;
&lt;li&gt;Reclaim budget&lt;/li&gt;
&lt;li&gt;Depot capacity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By validating these conditions on the cold path, we avoid putting any diagnostic, per-operation atomic accounting into the high-performance production hot path of &lt;code&gt;malloc&lt;/code&gt;/&lt;code&gt;free&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bounded Span Reclamation
&lt;/h3&gt;

&lt;p&gt;To ensure safety, HZ12 enforces a strict sequential contract during reclamation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Search for complete span candidates.&lt;/li&gt;
&lt;li&gt;Verify inbox and owner state.&lt;/li&gt;
&lt;li&gt;Check the reclaim budget.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pre-reserve depot capacity.&lt;/strong&gt; (Crucial!)&lt;/li&gt;
&lt;li&gt;Detach the route.&lt;/li&gt;
&lt;li&gt;Decommit the payload.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Roll back if any step fails.&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you decommit a span first and only then realize there is no space to store it, the span falls into a "limbo" state where it belongs to nowhere. To prevent this, &lt;strong&gt;depot capacity must be reserved prior to decommitting&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reclamation Results on Linux
&lt;/h3&gt;

&lt;p&gt;We measured owner turnover over 8 generations on Ubuntu/Linux x86-64.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Conditions:&lt;/strong&gt; 64 spans per generation, 64-byte objects, &lt;code&gt;RUNS=5&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;retirement p50&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1.089 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;retirement p99&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1.144 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;retirement max&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1.167 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;reclaimed spans&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;512 total&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;discarded bytes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;32 MiB total&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;limbo spans&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;peak RSS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;7.56 MiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;post RSS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3.56 MiB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We successfully reclaimed all 64/64 spans across all 8 generations. More importantly, &lt;strong&gt;the number of limbo spans was exactly 0&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Platform-Specific Implementations over Unified Code
&lt;/h2&gt;

&lt;p&gt;Instead of forcing a single implementation across operating systems, we separate the OS backing layers while sharing the core semantics.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Windows:&lt;/strong&gt; Uses &lt;code&gt;VirtualAlloc&lt;/code&gt; with &lt;code&gt;decommit&lt;/code&gt; / &lt;code&gt;recommit&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux:&lt;/strong&gt; Uses &lt;code&gt;mmap&lt;/code&gt; with &lt;code&gt;madvise(MADV_DONTNEED)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What they share is not the code itself, but the &lt;strong&gt;contract&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reclaim only complete spans.&lt;/li&gt;
&lt;li&gt;Keep budget and depot bounded.&lt;/li&gt;
&lt;li&gt;Roll back on failure.&lt;/li&gt;
&lt;li&gt;Never create limbo spans.&lt;/li&gt;
&lt;li&gt;Keep the speed lane and diagnostic lane strictly separated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We believe implementing the same contract tailored to each OS is far cleaner than squeezing them into a single, highly abstracted codebase.&lt;/p&gt;




&lt;h2&gt;
  
  
  Documenting the Failures (The "NO-GO" Experiments)
&lt;/h2&gt;

&lt;p&gt;In the Hakozuna project, we document not only the successful optimizations but also the experiments that ended up as "NO-GOs."&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Experiment&lt;/th&gt;
&lt;th&gt;Decision&lt;/th&gt;
&lt;th&gt;Reason&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Inbox capacity 2048/4096&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;CLOSED&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Expanding capacity violates our low RSS policy.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Per-operation atomic accounting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;NO-GO (Speed Lane)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Introduces too much fixed overhead on the hot path.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Incomplete reclaim snapshot&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;NO-GO&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fails to serve as a reliable safety authority.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Depot reservation after decommit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;MUST FIX&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Creates dangerous "limbo" spans.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lock-free per-free handoff&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;OUT OF SCOPE&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not the focus of the HZ12 architecture.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In allocator optimization, looking only at the "what went faster" results can easily lead to misinterpreting the actual design space. Documenting what we tried and &lt;em&gt;why&lt;/em&gt; we rejected it is just as valuable a research contribution.&lt;/p&gt;




&lt;h2&gt;
  
  
  Roles of HZ8, HZ11, and HZ12
&lt;/h2&gt;

&lt;p&gt;Here is how the current lineup is positioned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HZ8:&lt;/strong&gt; * General-purpose allocator.&lt;/li&gt;
&lt;li&gt;Balanced throughput and low post-workload RSS.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fail-closed ownership.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HZ11:&lt;/strong&gt; * Ownerless, speed-first baseline.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Built for throughput research.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HZ12:&lt;/strong&gt; * Advisory ownership and bounded span reclamation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Built for researching the trade-offs between speed and RSS.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HZ12 is not an absolute upgrade to HZ11. Managing ownership and lifecycles always introduces some overhead; for purely speed-oriented workloads, HZ11 may still have the upper hand. Additionally, we are not claiming that HZ12 replaces HZ8 at this stage.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The core question we wanted to answer with HZ10–HZ12 was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;How far can we balance the speed of ownerless recycling with efficient span reclamation, without adding owner lookups or diagnostic atomic operations to the malloc/free hot path?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Our current answer is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hot path:&lt;/strong&gt; Keep it short and completely ownerless.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cold path:&lt;/strong&gt; Narrow down candidates using advisory ownership, verify safety using complete-span validation, and cap the reclamation volume using a bounded budget and depot.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We haven't built a "silver bullet" allocator that completely replaces tcmalloc across the board. However, we have gained deep, practical insights into how to trade off speed, RSS, safety, and complexity within a unified allocator design.&lt;/p&gt;

&lt;p&gt;For a deeper dive into the architectural details and comprehensive benchmark data, please check out our paper and repository!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📄 &lt;strong&gt;HZ10-HZ12 Paper:&lt;/strong&gt; &lt;a href="https://doi.org/10.5281/zenodo.21360690" rel="noopener noreferrer"&gt;https://doi.org/10.5281/zenodo.21360690&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🐙 &lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/hakorune/hakozuna" rel="noopener noreferrer"&gt;https://github.com/hakorune/hakozuna&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cpp</category>
      <category>chatgpt</category>
    </item>
    <item>
      <title>Custom Memory Allocator HAKOZUNA HZ8: A balanced allocator that prioritizes low RSS over raw speed.</title>
      <dc:creator>CharmPic</dc:creator>
      <pubDate>Wed, 01 Jul 2026 07:48:19 +0000</pubDate>
      <link>https://dev.to/charmpic/custom-memory-allocator-hakozuna-hz8-a-balanced-allocator-that-prioritizes-low-rss-over-raw-speed-2lpp</link>
      <guid>https://dev.to/charmpic/custom-memory-allocator-hakozuna-hz8-a-balanced-allocator-that-prioritizes-low-rss-over-raw-speed-2lpp</guid>
      <description>

&lt;h1&gt;
  
  
  I have created HZ8 as a new line for my custom memory allocator, Hakozuna.
&lt;/h1&gt;

&lt;p&gt;HZ8 is not an allocator designed to be the "fastest across all benchmarks."&lt;/p&gt;

&lt;p&gt;The goal is to return the post-workload RSS to a low level while maintaining a practical throughput.&lt;/p&gt;

&lt;p&gt;In short, HZ8 is characterized as follows:&lt;/p&gt;

&lt;p&gt;HZ8:&lt;br&gt;
balanced low-RSS allocator&lt;br&gt;
practical throughput&lt;br&gt;
fail-closed ownership&lt;br&gt;
cross-thread free correctness&lt;/p&gt;

&lt;p&gt;I have consolidated the insights gained from experimenting with HZ3, HZ4, HZ5, and HZ6 into HZ8, organizing it as the primary allocator line to choose for general use.&lt;/p&gt;
&lt;h1&gt;
  
  
  HZ8 Design Principles
&lt;/h1&gt;

&lt;p&gt;In HZ8, we put a particular emphasis on the following points:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Keeping RSS low.&lt;/li&gt;
&lt;li&gt;Preventing breakdown under remote-heavy workloads.&lt;/li&gt;
&lt;li&gt;Handling cross-thread frees safely.&lt;/li&gt;
&lt;li&gt;Making ownership and route determination fail-closed.&lt;/li&gt;
&lt;li&gt;Balancing practical speed and memory usage rather than aiming for the absolute fastest.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The current default is HZ8-v2 / KeepRefill.&lt;/p&gt;

&lt;p&gt;KeepRefill is a mechanism designed to avoid heavy empty/reactivate loops under remote-heavy workloads. When a medium run becomes empty, it retains the owner-local refill candidate rather than destroying it immediately.&lt;/p&gt;
&lt;h1&gt;
  
  
  Benchmark Results
&lt;/h1&gt;

&lt;p&gt;The environment is Ubuntu 22.04.5 / Linux 6.8.0-90 / x86_64, RUNS=10, THREADS=16, ITERS=50000.&lt;/p&gt;

&lt;p&gt;The representative results are as follows:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Row&lt;/th&gt;
&lt;th&gt;HZ8 ops/s&lt;/th&gt;
&lt;th&gt;HZ8 post RSS&lt;/th&gt;
&lt;th&gt;mimalloc ops/s&lt;/th&gt;
&lt;th&gt;mimalloc post RSS&lt;/th&gt;
&lt;th&gt;tcmalloc ops/s&lt;/th&gt;
&lt;th&gt;tcmalloc post RSS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;small_interleaved_remote90&lt;/td&gt;
&lt;td&gt;12.023M&lt;/td&gt;
&lt;td&gt;2.91 MiB&lt;/td&gt;
&lt;td&gt;10.960M&lt;/td&gt;
&lt;td&gt;50.98 MiB&lt;/td&gt;
&lt;td&gt;23.900M&lt;/td&gt;
&lt;td&gt;32.94 MiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;main_interleaved_r90&lt;/td&gt;
&lt;td&gt;6.048M&lt;/td&gt;
&lt;td&gt;4.57 MiB&lt;/td&gt;
&lt;td&gt;4.715M&lt;/td&gt;
&lt;td&gt;183.12 MiB&lt;/td&gt;
&lt;td&gt;12.178M&lt;/td&gt;
&lt;td&gt;90.31 MiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;medium_interleaved_r50&lt;/td&gt;
&lt;td&gt;8.128M&lt;/td&gt;
&lt;td&gt;3.81 MiB&lt;/td&gt;
&lt;td&gt;4.151M&lt;/td&gt;
&lt;td&gt;162.54 MiB&lt;/td&gt;
&lt;td&gt;15.870M&lt;/td&gt;
&lt;td&gt;79.06 MiB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;tcmalloc shows strong throughput in many rows.&lt;/p&gt;

&lt;p&gt;On the other hand, HZ8 demonstrates significantly lower post-workload RSS.&lt;/p&gt;

&lt;p&gt;Therefore, the core proposition of HZ8 is as follows:&lt;/p&gt;

&lt;p&gt;HZ8 is not intended to fully replace tcmalloc.&lt;/p&gt;

&lt;p&gt;However, it is highly useful as an allocator that returns RSS to a low level while maintaining practical speed.&lt;/p&gt;
&lt;h3&gt;
  
  
  Comparison: MT lane x remote%
&lt;/h3&gt;

&lt;p&gt;Aligning HZ3, HZ4, HZ5, HZ6, and HZ8 makes the positioning of HZ8 slightly easier to visualize.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Lane&lt;/th&gt;
&lt;th&gt;hz3&lt;/th&gt;
&lt;th&gt;hz4&lt;/th&gt;
&lt;th&gt;mimalloc&lt;/th&gt;
&lt;th&gt;tcmalloc&lt;/th&gt;
&lt;th&gt;Best HZ5&lt;/th&gt;
&lt;th&gt;HZ6&lt;/th&gt;
&lt;th&gt;HZ8&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;main_r0&lt;/td&gt;
&lt;td&gt;292.15M&lt;/td&gt;
&lt;td&gt;85.63M&lt;/td&gt;
&lt;td&gt;146.73M&lt;/td&gt;
&lt;td&gt;318.82M&lt;/td&gt;
&lt;td&gt;157.44M&lt;/td&gt;
&lt;td&gt;16.88M&lt;/td&gt;
&lt;td&gt;107.633M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;main_r50&lt;/td&gt;
&lt;td&gt;31.46M&lt;/td&gt;
&lt;td&gt;62.32M&lt;/td&gt;
&lt;td&gt;14.26M&lt;/td&gt;
&lt;td&gt;64.87M&lt;/td&gt;
&lt;td&gt;79.43M&lt;/td&gt;
&lt;td&gt;15.08M&lt;/td&gt;
&lt;td&gt;29.633M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;main_r90&lt;/td&gt;
&lt;td&gt;22.31M&lt;/td&gt;
&lt;td&gt;67.14M&lt;/td&gt;
&lt;td&gt;7.72M&lt;/td&gt;
&lt;td&gt;45.42M&lt;/td&gt;
&lt;td&gt;62.31M&lt;/td&gt;
&lt;td&gt;10.99M&lt;/td&gt;
&lt;td&gt;20.610M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;guard_r0&lt;/td&gt;
&lt;td&gt;318.98M&lt;/td&gt;
&lt;td&gt;156.68M&lt;/td&gt;
&lt;td&gt;258.19M&lt;/td&gt;
&lt;td&gt;375.71M&lt;/td&gt;
&lt;td&gt;149.00M&lt;/td&gt;
&lt;td&gt;189.48M&lt;/td&gt;
&lt;td&gt;224.750M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cross128_r90&lt;/td&gt;
&lt;td&gt;2.78M&lt;/td&gt;
&lt;td&gt;27.66M&lt;/td&gt;
&lt;td&gt;3.52M&lt;/td&gt;
&lt;td&gt;7.21M&lt;/td&gt;
&lt;td&gt;22.39M&lt;/td&gt;
&lt;td&gt;6.38M&lt;/td&gt;
&lt;td&gt;37.342k&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;HZ8 is not universally fast.&lt;/p&gt;

&lt;p&gt;In particular, cross128_r90 is a current bottleneck.&lt;/p&gt;

&lt;p&gt;However, since HZ8 is a line focused heavily on keeping RSS low, it shouldn't be evaluated solely by throughput.&lt;/p&gt;
&lt;h1&gt;
  
  
  LargeDirect Experiment
&lt;/h1&gt;

&lt;p&gt;To address the weakness in cross128_r90, we also tested an opt-in profile called LargeDirectOwned.&lt;/p&gt;

&lt;p&gt;This provides evidence showing that the performance bottleneck in cross128_r90 stems from the large/direct boundary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;cross128_r90&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;baseline&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;62.940k ops/s&lt;/span&gt;
  &lt;span class="na"&gt;LargeDirect candidate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2.835M ops/s&lt;/span&gt;
  &lt;span class="na"&gt;ratio&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;45.048x&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;However, the RSS increases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;peak RSS:
  150.17 MiB -&amp;gt; 260.07 MiB

post RSS:
  107.04 MiB -&amp;gt; 190.61 MiB

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

&lt;/div&gt;



&lt;p&gt;For this reason, LargeDirect is not enabled by default.&lt;/p&gt;

&lt;p&gt;The default for HZ8 remains the KeepRefill balanced default.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;HZ8 is not the fastest allocator.&lt;/p&gt;

&lt;p&gt;However, it has become an allocator with the following distinct characteristics:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HZ8:
  Practical speed
  Low post-workload RSS
  Resilience against remote-heavy workloads
  Cross-thread free correctness
  Fail-closed ownership

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

&lt;/div&gt;



&lt;p&gt;If speed is the sole metric, tcmalloc remains incredibly strong.&lt;/p&gt;

&lt;p&gt;On the other hand, for workloads where returning RSS to a low level is critical, HZ8 occupies a very compelling position.&lt;/p&gt;

&lt;p&gt;Moving forward, we plan to maintain the balanced line of HZ8 while advancing further speed-oriented research under HZ9.&lt;/p&gt;

&lt;h1&gt;
  
  
  Links
&lt;/h1&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/hakorune/hakozuna" rel="noopener noreferrer"&gt;https://github.com/hakorune/hakozuna&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;HZ8 paper / Zenodo: &lt;a href="https://zenodo.org/records/21084279" rel="noopener noreferrer"&gt;https://zenodo.org/records/21084279&lt;/a&gt;&lt;/p&gt;

</description>
      <category>c</category>
      <category>chatgpt</category>
    </item>
    <item>
      <title>Hakozuna HZ5: Page/Runfast Sidecar Allocator Prototype Design Notes</title>
      <dc:creator>CharmPic</dc:creator>
      <pubDate>Wed, 27 May 2026 12:46:50 +0000</pubDate>
      <link>https://dev.to/charmpic/hakozuna-hz5-pagerunfast-sidecar-allocator-prototype-design-notes-525j</link>
      <guid>https://dev.to/charmpic/hakozuna-hz5-pagerunfast-sidecar-allocator-prototype-design-notes-525j</guid>
      <description>&lt;h1&gt;
  
  
  Hakozuna HZ5: Design Notes for a Page/Run-First Sidecar Allocator Prototype
&lt;/h1&gt;

&lt;p&gt;In this post, I will outline the design principles for &lt;strong&gt;HZ5&lt;/strong&gt;, a new experimental prototype within &lt;strong&gt;Hakozuna&lt;/strong&gt;, a memory allocator project implemented in C.&lt;/p&gt;

&lt;p&gt;Up until now, Hakozuna has evolved primarily around the HZ3 and HZ4 allocator profiles. HZ5 is an extension of that lineage, but it isn't just a branch aimed at slightly accelerating the existing fast path.&lt;/p&gt;

&lt;p&gt;In HZ5, we are revisiting the internal architecture of the allocator to explore the following directions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Page/Run-first classification&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sidecar metadata&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fail-closed ownership determination&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Descriptor-owned front-end&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Page-oriented remote free&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Profile-specific allocator lanes&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Experimental build/benchmark paths for Linux and Windows&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rather than a finished product, HZ5 serves as a testbed for rethinking allocator design.&lt;/p&gt;




&lt;h2&gt;
  
  
  Differences Between HZ3, HZ4, and HZ5
&lt;/h2&gt;

&lt;p&gt;Hakozuna is categorized into several distinct allocator profiles:&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;HZ3 / ACE-Alloc&lt;/strong&gt; is a profile primarily designed for local-heavy allocation workloads. It focuses on compact memory usage and O(1) pointer-to-bin lookups using PTAG32.&lt;/p&gt;

&lt;p&gt;Next, &lt;strong&gt;HZ4&lt;/strong&gt; is a message-passing / remote-free profile. It is intended for remote-heavy workloads and scenarios with high thread counts.&lt;/p&gt;

&lt;p&gt;In contrast, &lt;strong&gt;HZ5&lt;/strong&gt; is a &lt;strong&gt;page/run-first sidecar allocator prototype&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The differences can be summarized as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HZ3 / HZ4:
  Polishing existing profiles.
  Optimizing small object paths and remote-free paths.

HZ5:
  Reimagining classification, ownership, and metadata layout.
  Designing around pages/runs and descriptors.

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

&lt;/div&gt;



&lt;p&gt;While HZ3 and HZ4 focus on "strengthening existing profiles," HZ5 is a prototype for "reconstructing the internal structure of the allocator from a different perspective."&lt;/p&gt;




&lt;h2&gt;
  
  
  HZ5 Design Principles
&lt;/h2&gt;

&lt;p&gt;The core of HZ5 is the concept of &lt;strong&gt;classifying pointers in page/run units and consolidating that information into sidecar descriptors.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When performing a &lt;code&gt;free&lt;/code&gt;, the allocator needs to determine at least the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does this pointer belong to this allocator? (Ownership)&lt;/li&gt;
&lt;li&gt;Which size class, run, or page does it belong to?&lt;/li&gt;
&lt;li&gt;Can it be returned locally, or should it be treated as a remote free?&lt;/li&gt;
&lt;li&gt;Which front-end or profile should it be dispatched to?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Instead of forcing this metadata to be stored immediately adjacent to the pointer itself, HZ5 explores a direction centered on descriptors corresponding to pages/runs.&lt;/p&gt;

&lt;p&gt;The flow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user pointer
    |
    v
page / run lookup
    |
    v
sidecar descriptor
    |
    +--&amp;gt; owner
    +--&amp;gt; profile
    +--&amp;gt; size class
    +--&amp;gt; front-end policy
    |
    v
allocation / free dispatch

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

&lt;/div&gt;



&lt;p&gt;Crucially, HZ5 is not just about "placing metadata outside." By shifting metadata to a sidecar, we can centralize ownership, profile, and dispatch policy within the descriptor. This means that instead of each front-end making independent decisions, the descriptor dictates "how this pointer should be handled."&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Sidecar Metadata?
&lt;/h2&gt;

&lt;p&gt;One of the hardest parts of an allocator is the &lt;code&gt;free(ptr)&lt;/code&gt; operation.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;malloc(size)&lt;/code&gt;, the requested size is explicit. However, with &lt;code&gt;free(ptr)&lt;/code&gt;, only a pointer is provided. The allocator must recover the owner, size class, and return destination from that pointer alone.&lt;/p&gt;

&lt;p&gt;Consequently, the placement of metadata is critical.&lt;/p&gt;

&lt;p&gt;Some designs place metadata close to the user allocation, which can be advantageous for locality and implementation simplicity. HZ5, however, tests a page/run unit descriptor approach, where the allocator looks up the descriptor via the pointer's page/run.&lt;/p&gt;

&lt;p&gt;This design emphasizes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clarifying pointer classification at the page/run level.&lt;/li&gt;
&lt;li&gt;Centralizing ownership logic within the descriptor.&lt;/li&gt;
&lt;li&gt;Organizing policy dispatch for each profile.&lt;/li&gt;
&lt;li&gt;Opting for a &lt;strong&gt;fail-closed&lt;/strong&gt; approach for unknown pointers or ambiguous states.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this context, "fail-closed" means that instead of "proceeding despite uncertainty," the system defaults to the safe side if ownership cannot be confirmed.&lt;/p&gt;

&lt;p&gt;In high-speed allocators, there is a temptation to eliminate every extra branch or lookup. However, allocator ownership logic is a high-impact area if corrupted. In HZ5, the clarity of classification is as much a design goal as raw speed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Current State of the Windows Port
&lt;/h2&gt;

&lt;p&gt;While HZ5 began as an experiment on Linux, we are now establishing native Windows build and benchmark paths.&lt;/p&gt;

&lt;p&gt;However, I want to be cautious here: HZ5 is still &lt;strong&gt;experimental&lt;/strong&gt;. It is not yet at a stage where it can generally replace existing allocators across the Windows ecosystem.&lt;/p&gt;

&lt;p&gt;Its current role is as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Establishing the pipeline for native Windows builds.&lt;/li&gt;
&lt;li&gt;Enabling profile-specific benchmarks on Windows.&lt;/li&gt;
&lt;li&gt;Observing workload trends (remote-heavy, local-heavy, mixed, etc.).&lt;/li&gt;
&lt;li&gt;Comparing how designs formulated on Linux translate to the Windows environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Allocator benchmarks vary wildly depending on the environment. Factors such as OS, compiler, thread count, allocation size distribution, remote-free ratios, and RSS management all shift the results. Therefore, it is safer to treat HZ5 results not as "globally faster on Windows," but as "exhibiting these tendencies in this specific profile/benchmark lane."&lt;/p&gt;




&lt;h2&gt;
  
  
  Notes on Interpreting Benchmarks
&lt;/h2&gt;

&lt;p&gt;It is difficult to judge an allocator by a single number.&lt;/p&gt;

&lt;p&gt;High throughput may come at the cost of excessive RSS. An allocator that excels in local-heavy workloads might struggle when remote frees increase. Performance with small objects might not translate to large allocations or mixed workloads.&lt;/p&gt;

&lt;p&gt;As such, HZ5 evaluates benchmarks across several axes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local-heavy vs. Remote-heavy.&lt;/li&gt;
&lt;li&gt;Small object focused vs. Mixed size.&lt;/li&gt;
&lt;li&gt;Throughput vs. RSS.&lt;/li&gt;
&lt;li&gt;Scalability with increased thread counts.&lt;/li&gt;
&lt;li&gt;Consistency between Linux and Windows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The danger in allocator evaluation is claiming it is the "best" based on a single successful case. HZ5 is not for making such claims. Rather, it is an experiment to see what happens when the allocator's structure is varied by profile.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Assign a DOI?
&lt;/h2&gt;

&lt;p&gt;We have assigned a &lt;strong&gt;DOI via Zenodo&lt;/strong&gt; to HZ5 for this release.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HZ5 Zenodo record:&lt;/strong&gt; &lt;a href="https://zenodo.org/records/20411598" rel="noopener noreferrer"&gt;https://zenodo.org/records/20411598&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HZ5 DOI:&lt;/strong&gt; &lt;a href="https://doi.org/10.5281/zenodo.20411598" rel="noopener noreferrer"&gt;https://doi.org/10.5281/zenodo.20411598&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HZ5 all-version DOI:&lt;/strong&gt; &lt;a href="https://doi.org/10.5281/zenodo.20411597" rel="noopener noreferrer"&gt;https://doi.org/10.5281/zenodo.20411597&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Note: HZ3/HZ4 also has its own separate artifact DOI.)&lt;/p&gt;

&lt;p&gt;GitHub repositories are updated daily, which is great for development but problematic for citing a specific version of a paper, source, or artifact. A Zenodo DOI allows us to freeze the deliverables at a specific point in time.&lt;/p&gt;

&lt;p&gt;The HZ5 artifact includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HZ5 source code&lt;/li&gt;
&lt;li&gt;Design notes&lt;/li&gt;
&lt;li&gt;Benchmarks and reproducibility artifacts&lt;/li&gt;
&lt;li&gt;English and Japanese paper PDFs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Separating the DOIs for HZ3/HZ4 and HZ5 was intentional. HZ3/HZ4 focuses on the maturity and comparison of existing profiles, while HZ5 represents a different design line as a sidecar allocator prototype. Keeping them separate makes the intent clearer for readers and researchers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Future Outlook
&lt;/h2&gt;

&lt;p&gt;HZ5 is not "finished"; it has simply reached a stage where its form is organized enough to be shared.&lt;/p&gt;

&lt;p&gt;Moving forward, I aim to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Refine the Windows HZ5 path.&lt;/li&gt;
&lt;li&gt;Expand Linux/Windows benchmark coverage.&lt;/li&gt;
&lt;li&gt;Categorize stability by profile.&lt;/li&gt;
&lt;li&gt;Consolidate comparisons with HZ3/HZ4.&lt;/li&gt;
&lt;li&gt;Synchronize papers, READMEs, and artifacts.&lt;/li&gt;
&lt;li&gt;Further streamline reproducibility procedures.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The behavior of an allocator can change drastically based on minor implementation details. This is exactly why we need to clarify which profile is effective for which workload under what constraints, rather than just saying it's "fast."&lt;/p&gt;

&lt;p&gt;HZ5 is the testbed for that inquiry.&lt;/p&gt;

&lt;p&gt;We still need to verify the effectiveness of page/run-first classification, sidecar descriptors, fail-closed ownership, and profile-specific dispatch. However, with this milestone, HZ5 has transitioned from a "prototype folder in a repo" to a "research artifact with design intent and a DOI."&lt;/p&gt;

&lt;p&gt;I look forward to growing it further, step by step.&lt;/p&gt;

</description>
      <category>c</category>
      <category>malloc</category>
      <category>hakozuna</category>
    </item>
    <item>
      <title>Finishing Hakozuna HZ5: From Experimental Allocator to DOI-Archived Artifact</title>
      <dc:creator>CharmPic</dc:creator>
      <pubDate>Wed, 27 May 2026 12:25:37 +0000</pubDate>
      <link>https://dev.to/charmpic/reviving-hakozuna-hz5-from-allocator-prototype-to-citable-research-artifact-22df</link>
      <guid>https://dev.to/charmpic/reviving-hakozuna-hz5-from-allocator-prototype-to-citable-research-artifact-22df</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-05-21"&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Reviving Hakozuna HZ5: From Allocator Sidecar Prototype to Citable Research Artifact
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built and revived &lt;strong&gt;Hakozuna HZ5&lt;/strong&gt;, an experimental page/run-first sidecar allocator prototype written in C.&lt;/p&gt;

&lt;p&gt;Hakozuna started as a personal allocator research project. Earlier versions focused on the HZ3/HZ4 allocator profiles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HZ3 / ACE-Alloc&lt;/strong&gt;: a compact, local-heavy allocation profile using PTAG32-based O(1) pointer-to-bin lookup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HZ4&lt;/strong&gt;: a remote-free / message-passing profile for remote-heavy and high-thread-count workloads.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HZ5 is the next experimental branch of that work. Instead of only optimizing the existing small-object paths, HZ5 explores a more structural design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;page/run-first allocation&lt;/li&gt;
&lt;li&gt;sidecar metadata&lt;/li&gt;
&lt;li&gt;fail-closed ownership checks&lt;/li&gt;
&lt;li&gt;descriptor-owned front-ends&lt;/li&gt;
&lt;li&gt;page-oriented remote free&lt;/li&gt;
&lt;li&gt;profile-specific Linux allocator lanes&lt;/li&gt;
&lt;li&gt;an active experimental Windows native build/benchmark path&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project matters to me because it is not only code. It is a record of trying to turn allocator experiments into something reproducible, understandable, and citable. This finish-up pass was about taking HZ5 from "interesting prototype in the tree" to "documented artifact that another person can inspect, cite, and build on."&lt;/p&gt;

&lt;p&gt;Project links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub repository: &lt;a href="https://github.com/hakorune/hakozuna" rel="noopener noreferrer"&gt;https://github.com/hakorune/hakozuna&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;HZ5 Zenodo record: &lt;a href="https://zenodo.org/records/20411598" rel="noopener noreferrer"&gt;https://zenodo.org/records/20411598&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;HZ5 DOI: &lt;a href="https://doi.org/10.5281/zenodo.20411598" rel="noopener noreferrer"&gt;https://doi.org/10.5281/zenodo.20411598&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;HZ5 all-version DOI: &lt;a href="https://doi.org/10.5281/zenodo.20411597" rel="noopener noreferrer"&gt;https://doi.org/10.5281/zenodo.20411597&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;HZ3/HZ4 Zenodo record: &lt;a href="https://zenodo.org/records/20411402" rel="noopener noreferrer"&gt;https://zenodo.org/records/20411402&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;HZ3/HZ4 DOI: &lt;a href="https://doi.org/10.5281/zenodo.20411402" rel="noopener noreferrer"&gt;https://doi.org/10.5281/zenodo.20411402&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;The main demo is the repository and the archived research artifact.&lt;/p&gt;

&lt;p&gt;Recommended screenshots or captures to include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repository top page showing the Hakozuna README and DOI badges.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hakozuna-hz5/&lt;/code&gt; directory showing the HZ5 source layout.&lt;/li&gt;
&lt;li&gt;Windows build documentation showing the active native Windows path.&lt;/li&gt;
&lt;li&gt;Zenodo HZ5 record page showing the DOI and uploaded English/Japanese PDFs.&lt;/li&gt;
&lt;li&gt;Benchmark or reproducibility documentation from the HZ5 docs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If adding a short video walkthrough, I would show:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The root repository README and how HZ3/HZ4 and HZ5 are separated.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;hakozuna-hz5/&lt;/code&gt; directory layout.&lt;/li&gt;
&lt;li&gt;The Linux and Windows documentation entry points.&lt;/li&gt;
&lt;li&gt;The HZ5 design notes and benchmark documentation.&lt;/li&gt;
&lt;li&gt;The Zenodo DOI page that archives the HZ5 paper PDFs and artifacts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Suggested video title:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hakozuna HZ5 walkthrough: allocator prototype, docs, benchmark notes, and DOI archive&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Comeback Story
&lt;/h2&gt;

&lt;p&gt;Before this finish-up pass, HZ5 existed as a promising allocator prototype, but the project was still hard to understand from the outside.&lt;/p&gt;

&lt;p&gt;The core ideas were there:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;page/run-first allocation&lt;/li&gt;
&lt;li&gt;sidecar metadata&lt;/li&gt;
&lt;li&gt;descriptor/policy separation&lt;/li&gt;
&lt;li&gt;Linux profile experiments&lt;/li&gt;
&lt;li&gt;Windows native build and benchmark notes&lt;/li&gt;
&lt;li&gt;benchmark and reproducibility notes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the presentation was not finished. HZ5 was still mixed into the broader Hakozuna story, the top-level README still made the project feel mostly Linux-research oriented, and the relationship between HZ3/HZ4 and HZ5 was not clear enough for a reader landing on the repository for the first time.&lt;/p&gt;

&lt;p&gt;The comeback work focused on turning the prototype into a clean research artifact:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clarified HZ5 as a separate experimental profile next to HZ3/HZ4&lt;/li&gt;
&lt;li&gt;prepared English and Japanese paper PDFs&lt;/li&gt;
&lt;li&gt;published the HZ5 artifact on Zenodo&lt;/li&gt;
&lt;li&gt;assigned a citable DOI to HZ5&lt;/li&gt;
&lt;li&gt;updated README links so HZ3/HZ4 and HZ5 have separate DOI references&lt;/li&gt;
&lt;li&gt;clarified the current Windows HZ5 path as experimental and actively being developed&lt;/li&gt;
&lt;li&gt;documented the artifact contents, source layout, and reproducibility materials&lt;/li&gt;
&lt;li&gt;made the repository easier to navigate for future readers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most important change was not one single optimization. It was making the project legible.&lt;/p&gt;

&lt;p&gt;An unfinished allocator prototype can be valuable, but it is fragile if the design context only exists in the author's head. This pass made HZ5 easier to preserve, cite, and continue.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Experience with GitHub Copilot
&lt;/h2&gt;

&lt;p&gt;I used GitHub Copilot as a finishing and review partner, not as a replacement for the allocator design work.&lt;/p&gt;

&lt;p&gt;For this project, that distinction matters. HZ5 is low-level C allocator work, so I did not want AI to blindly rewrite memory-management logic or make benchmark claims for me. The core allocator design, implementation direction, and benchmark interpretation were driven by my own work and manually checked.&lt;/p&gt;

&lt;p&gt;Copilot helped in the finishing stage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;polishing the README direction&lt;/li&gt;
&lt;li&gt;reviewing the DEV post narrative&lt;/li&gt;
&lt;li&gt;checking whether the public repository had enough entry points for readers&lt;/li&gt;
&lt;li&gt;helping separate the HZ3/HZ4 and HZ5 artifact story&lt;/li&gt;
&lt;li&gt;keeping the claims scoped to the actual profiles and platforms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also used other AI tools for discussion and drafting, and I am disclosing that openly. The useful pattern was not "AI writes the project." It was closer to having an extra reviewer asking: is the story clear, are the links findable, is the scope honest, and would a new reader know where to start?&lt;/p&gt;

&lt;p&gt;That was exactly the kind of help this project needed. HZ5 did not need to be reinvented. It needed to be made understandable, archived, and easier to continue.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Changed Technically
&lt;/h2&gt;

&lt;p&gt;HZ5 is organized as a page/run-first sidecar allocator prototype.&lt;/p&gt;

&lt;p&gt;Important areas include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;hakozuna-hz5/&lt;/code&gt;: HZ5 allocator source&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;api/&lt;/code&gt;: public allocator API surface&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;contract/&lt;/code&gt;: SpeedLane descriptor ABI and purity contract&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;policy/&lt;/code&gt;: HZ5-native allocation/free dispatch policy&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;lowpage/&lt;/code&gt;, &lt;code&gt;midpagefront/&lt;/code&gt;, and &lt;code&gt;largefront/&lt;/code&gt;: experimental page/run front-ends&lt;/li&gt;
&lt;li&gt;Linux benchmark scripts and profile matrices&lt;/li&gt;
&lt;li&gt;Windows native build and benchmark documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The HZ5 design direction is different from simply tuning the previous allocator profile. It treats page/run ownership, metadata, and profile dispatch as first-class design concerns.&lt;/p&gt;

&lt;p&gt;That makes HZ5 useful as a research branch even when individual benchmark lanes are still experimental. I am intentionally keeping performance claims profile-scoped: the interesting results are tied to specific allocator lanes, workloads, and platforms, not a blanket claim that HZ5 is universally faster everywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;Finishing a research-code project is not only about writing more code.&lt;/p&gt;

&lt;p&gt;For this project, "finished enough to share" meant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the source is present&lt;/li&gt;
&lt;li&gt;the design intent is written down&lt;/li&gt;
&lt;li&gt;benchmark and reproducibility notes exist&lt;/li&gt;
&lt;li&gt;the artifact is archived&lt;/li&gt;
&lt;li&gt;the DOI is stable&lt;/li&gt;
&lt;li&gt;the README tells readers where to start&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest lesson was that a prototype becomes much more useful when its boundaries are clear.&lt;/p&gt;

&lt;p&gt;HZ5 is not just "the next allocator folder." It is now a named artifact with its own DOI, its own design story, and its own place next to HZ3/HZ4.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;Next steps for HZ5:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;continue Linux allocator profile experiments&lt;/li&gt;
&lt;li&gt;continue the active Windows port and native benchmark path&lt;/li&gt;
&lt;li&gt;improve benchmark coverage&lt;/li&gt;
&lt;li&gt;clarify which HZ5 lanes are stable research artifacts and which are exploratory&lt;/li&gt;
&lt;li&gt;add more reproducibility notes&lt;/li&gt;
&lt;li&gt;keep HZ3/HZ4 and HZ5 documentation separated but cross-linked&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The comeback is not the end of HZ5. It is the point where the project becomes easier to continue.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
    </item>
    <item>
      <title>Language Barriers: A Struggle for Japanese Developers on Dev.to</title>
      <dc:creator>CharmPic</dc:creator>
      <pubDate>Sun, 12 Apr 2026 06:58:52 +0000</pubDate>
      <link>https://dev.to/charmpic/language-barriers-a-struggle-for-japanese-developers-on-devto-kjc</link>
      <guid>https://dev.to/charmpic/language-barriers-a-struggle-for-japanese-developers-on-devto-kjc</guid>
      <description>&lt;p&gt;As a Japanese developer, I love browsing Dev.to to keep up with the latest tech trends. However, I often face a significant "wall" that hinders my learning experience: the language barrier.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The "I Can't Read English Fast Enough" Problem&lt;br&gt;
Let’s be honest—reading long technical articles in English is exhausting when it's not your native language. Even if a headline looks incredibly interesting, the psychological hurdle of clicking on a wall of English text is surprisingly high.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Limitations of Browser Translation&lt;br&gt;
You might say, "Just use Google Translate or built-in browser features!" But it’s not that simple:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Friction: Having to manually trigger translation for every single page is a tedious extra step.&lt;/p&gt;

&lt;p&gt;Accuracy: Standard browser translations often struggle with technical context. They sometimes mangle code snippets or turn specific jargon into nonsensical Japanese, forcing me to switch back to the original text anyway.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Dream Feature: AI-Powered Native Translation
I often find myself wishing Dev.to would implement an integrated AI translation feature.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With the power of modern LLMs, we could have context-aware, high-quality translations at the click of a button. Imagine a "Read in Japanese" toggle right next to the article!&lt;/p&gt;

&lt;p&gt;I understand that API costs are a major concern, making this a difficult feature to implement for free. But it’s painful to think about how many amazing insights I’m missing out on just because of the language gap. T^T&lt;/p&gt;

&lt;p&gt;I’d love to hear from you:&lt;br&gt;
How do non-native English speakers handle this? Do you use any specific tools or extensions that make your Dev.to experience smoother?&lt;/p&gt;

</description>
      <category>community</category>
      <category>devjournal</category>
      <category>discuss</category>
      <category>learning</category>
    </item>
    <item>
      <title>Re-evaluating the ROI of GLM-5.1 Pro After a Massive Price Hike to $680</title>
      <dc:creator>CharmPic</dc:creator>
      <pubDate>Sun, 12 Apr 2026 06:29:49 +0000</pubDate>
      <link>https://dev.to/charmpic/re-evaluating-the-roi-of-glm-51-pro-after-a-massive-price-hike-to-680-i2d</link>
      <guid>https://dev.to/charmpic/re-evaluating-the-roi-of-glm-51-pro-after-a-massive-price-hike-to-680-i2d</guid>
      <description>&lt;p&gt;Headline: GLM-5.1 Pro Price Hike: 3x Increase to $680/year — Time to Look for Alternatives?&lt;/p&gt;

&lt;p&gt;I recently received some shocking news regarding the GLM-5.1 Pro plan.&lt;br&gt;
The annual subscription, which used to be a reasonable $180, has suddenly spiked to over $680. That is a staggering 3x increase.&lt;/p&gt;

&lt;p&gt;To be fair, the GLM-5.1 Pro plan offered incredible value. Its performance and limits were comparable to the Claude Code $200/month (Max) tier, making it a "hidden gem" for developers. Even at $680/year, one could argue it still offers decent value considering the high-end capabilities.&lt;/p&gt;

&lt;p&gt;However, a 600% price jump changes the equation. At this price point, we can no longer ignore other major AI players in the market. It’s time to start comparing the cost-to-performance ratio against other leading LLMs again.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>news</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Instant Glory: The App That Makes Every Coder a DEV Challenge Winner</title>
      <dc:creator>CharmPic</dc:creator>
      <pubDate>Fri, 10 Apr 2026 17:20:15 +0000</pubDate>
      <link>https://dev.to/charmpic/instant-glory-the-app-that-makes-every-coder-a-dev-challenge-winner-1fmo</link>
      <guid>https://dev.to/charmpic/instant-glory-the-app-that-makes-every-coder-a-dev-challenge-winner-1fmo</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/aprilfools-2026"&gt;DEV April Fools Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The Ultimate Ego Booster: Challenge Winner Simulator 2026
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Have you ever felt the unbearable emptiness of not winning a DEV challenge? The sleepless nights. The existential dread. The nagging suspicion that your code may not be "useless" enough to qualify for greatness?&lt;/p&gt;

&lt;p&gt;I built a gloriously unnecessary victory machine that solves all of that.&lt;/p&gt;

&lt;p&gt;Challenge Winner Simulator 2026 is a delightfully over-the-top praise engine: enter your name, and the app transforms into a full-blown cosmic celebration of your alleged brilliance. You get dramatic compliments, absurd statistics, galactic proclamations, a cinematic Star Wars-style credit crawl, and enough visual excess to convince any developer that they are, in fact, the chosen one.&lt;/p&gt;

&lt;p&gt;And because the joke simply refused to stay in the browser, I also built a Windows desktop version of the app with Flutter and WebView2. So now the same majestic nonsense can be launched as a native Windows app, packaged like a serious piece of software despite being fundamentally unserious in every possible way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Web demo:&lt;br&gt;&lt;br&gt;
&lt;a href="https://moe-charm.github.io/dev_challenges/20260411winner/index.html" rel="noopener noreferrer"&gt;https://moe-charm.github.io/dev_challenges/20260411winner/index.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Windows release:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/moe-charm/dev_challenges/releases/tag/winner-simulator-20260411" rel="noopener noreferrer"&gt;https://github.com/moe-charm/dev_challenges/releases/tag/winner-simulator-20260411&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Click the "CELEBRATE!" button to trigger the full auditory and visual experience.&lt;br&gt;&lt;br&gt;
And yes, the music absolutely matters.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And because the joke simply refused to stay in the browser, I also built a Windows desktop version of the app with Flutter and WebView2. So now the same majestic nonsense can be launched as a native Windows app, packaged like a serious piece of software despite being fundamentally unserious in every possible way. And since this is an April Fools project, you can enjoy the whole thing locally anytime, even offline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;Web version:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/moe-charm/dev_challenges/tree/main/20260411winner" rel="noopener noreferrer"&gt;https://github.com/moe-charm/dev_challenges/tree/main/20260411winner&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Windows version:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/moe-charm/dev_challenges/tree/main/winner_simulator_app" rel="noopener noreferrer"&gt;https://github.com/moe-charm/dev_challenges/tree/main/winner_simulator_app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Release build:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/moe-charm/dev_challenges/releases/tag/winner-simulator-20260411" rel="noopener noreferrer"&gt;https://github.com/moe-charm/dev_challenges/releases/tag/winner-simulator-20260411&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;I wanted this to feel both ridiculous and weirdly overengineered, so I kept the web version lightweight while piling on just enough spectacle to make it feel expensive.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vanilla HTML/CSS/JS: no framework, no mercy, just pure DOM manipulation and theatrical confidence.&lt;/li&gt;
&lt;li&gt;CSS transforms and animations: used for the big cinematic crawl, dramatic fades, glowing text, and all the unnecessary grandeur.&lt;/li&gt;
&lt;li&gt;Canvas API: used for fireworks and particle effects so the whole thing could sparkle like it was accepting an award nobody asked for.&lt;/li&gt;
&lt;li&gt;Web Audio API: used for fanfares, drum rolls, cat-like sounds, and the kind of BGM that insists your name deserves a standing ovation.&lt;/li&gt;
&lt;li&gt;i18n logic: supports both English and Japanese, because winning should be internationally embarrassing.&lt;/li&gt;
&lt;li&gt;Flutter + WebView2: for the Windows desktop edition, which embeds the same HTML challenge into a standalone app so the joke can live outside the browser too.&lt;/li&gt;
&lt;li&gt;Embedded assets: the Windows build packages the challenge inside the app, so it can be distributed as a release ZIP without needing a separate content folder.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The whole project is intentionally excessive for something fundamentally useless, which is exactly what made it fun to build.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Category
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Best Ode to Larry Masinter&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This project is basically a shrine to the spirit of playful protocol absurdity. It leans hard into the glorious nonsense of &lt;code&gt;418 I'm a teapot&lt;/code&gt;, celebrates the ritual of turning a tiny joke into a grand experience, and fully embraces the idea that the web can be both technically elaborate and completely ridiculous at the same time.&lt;/p&gt;

&lt;p&gt;The Golden Teapot is not just a trophy. It is a philosophy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Google AI Usage (Best Google AI Usage Entry)
&lt;/h3&gt;

&lt;p&gt;This entire project was built in a deep pair-programming session with &lt;strong&gt;Antigravity&lt;/strong&gt;, Google’s agentic AI coding assistant. &lt;br&gt;
Antigravity wasn't just a code generator; it acted as a "Dramatic Consultant" and "Vibe Architect." Here’s how we used it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rapid Prototyping&lt;/strong&gt;: Antigravity generated the complex CSS 3D transforms for the credit crawl and the Canvas-based firework engine from scratch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agentic Iteration&lt;/strong&gt;: We iterated on the visual "wow factor" by asking the AI to "make it more over-the-top" and "add more galactic energy," which led to the inclusion of glitch effects, screen shakes, and dynamic starfields.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Creative Writing&lt;/strong&gt;: The AI helped craft the hyperbolic, universe-shattering narratives in the crawl and world reaction sections, ensuring the "uselessness" was presented with the highest possible prestige.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sound Engineering&lt;/strong&gt;: The AI assisted in integrating the Web Audio API for real-time sound synthesis while managing the external BGM integration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-Platform Escalation&lt;/strong&gt;: When our ambitions got too big and we decided to build a native offline Windows desktop app via Flutter, the AI (along with a strategic assist from ChatGPT for Windows WebView2 virtual hosting) helped us bypass local CORS restrictions and materialize the embedded assets natively!
The collaboration felt less like "writing code" and more like "directing a digital movie." AI allowed me to focus on the humor and vision while it handled the heavy lifting of the visual and auditory implementation.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>418challenge</category>
      <category>showdev</category>
    </item>
    <item>
      <title>NyanZip: The Delightfully Useless Cat-Language Compression App</title>
      <dc:creator>CharmPic</dc:creator>
      <pubDate>Fri, 03 Apr 2026 04:44:05 +0000</pubDate>
      <link>https://dev.to/charmpic/nyanzip-the-delightfully-useless-cat-language-compression-app-5gj7</link>
      <guid>https://dev.to/charmpic/nyanzip-the-delightfully-useless-cat-language-compression-app-5gj7</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/aprilfools-2026"&gt;DEV April Fools Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  NyanZip: The Delightfully Useless Cat-Language Compression App
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built NyanZip, a browser-based joke app that takes normal text and turns it into exaggerated cat language.&lt;/p&gt;

&lt;p&gt;It has two modes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A playful "compress" mode that expands text into a noisy stream of &lt;code&gt;meow&lt;/code&gt; and &lt;code&gt;MEOW!!&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;An "ultra" mode that uses real compression under the hood, but still wraps everything in cat-themed nonsense&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also includes optional Gemini-powered cat commentary, because every compression tool deserves a tiny, judgmental reviewer in a bow tie.&lt;/p&gt;

&lt;p&gt;The result is intentionally impractical, a little chaotic, and exactly the kind of project that feels right for April Fools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Live demo: &lt;a href="https://moe-charm.github.io/dev_challenges/20260402april/" rel="noopener noreferrer"&gt;https://moe-charm.github.io/dev_challenges/20260402april/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Repository: &lt;a href="https://github.com/moe-charm/dev_challenges" rel="noopener noreferrer"&gt;https://github.com/moe-charm/dev_challenges&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;The code is all in the repository above. The main pieces are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App shell and UI: &lt;code&gt;20260402april/index.html&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Main interaction logic: &lt;code&gt;20260402april/app.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Cat-text encoder and decoder: &lt;code&gt;20260402april/js/engine.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Ultra compression pipeline: &lt;code&gt;20260402april/js/rans.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Optional AI cat review feature: &lt;code&gt;20260402april/js/chat.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Localization strings: &lt;code&gt;20260402april/js/i18n.js&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;I built NyanZip with plain HTML, CSS, and JavaScript.&lt;/p&gt;

&lt;p&gt;A few things made it fun to put together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;TextEncoder&lt;/code&gt; and &lt;code&gt;TextDecoder&lt;/code&gt; for converting text to bytes and back&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CompressionStream&lt;/code&gt; and &lt;code&gt;DecompressionStream&lt;/code&gt; for the ultra mode&lt;/li&gt;
&lt;li&gt;A simple bilingual UI for Japanese and English&lt;/li&gt;
&lt;li&gt;Optional Gemini integration for the cat review comments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also published it with GitHub Pages so the joke works directly in the browser, with no setup required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Category
&lt;/h2&gt;

&lt;p&gt;I’d submit this for &lt;strong&gt;Community Favorite&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is intentionally silly, easy to try, and built to make people smile first and ask questions later. The optional Google AI feature adds a fun extra layer, but the core joke stands on its own.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>418challenge</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Hakozuna v3.2 Released: Bringing Optimized Memory Allocation to M1 Mac</title>
      <dc:creator>CharmPic</dc:creator>
      <pubDate>Thu, 19 Mar 2026 23:29:20 +0000</pubDate>
      <link>https://dev.to/charmpic/hakozuna-v32-released-bringing-optimized-memory-allocation-to-m1-mac-b7m</link>
      <guid>https://dev.to/charmpic/hakozuna-v32-released-bringing-optimized-memory-allocation-to-m1-mac-b7m</guid>
      <description>&lt;p&gt;I've added the main text to chatgpt5.4 ↓&lt;/p&gt;

&lt;p&gt;I am pleased to announce the release of Hakozuna v3.2.&lt;br&gt;
While my previous update focused on Windows, this release marks a significant milestone: Full support for M1 Mac.&lt;/p&gt;

&lt;p&gt;GitHub Release:&lt;a href="https://github.com/hakorune/hakozuna" rel="noopener noreferrer"&gt;https://github.com/hakorune/hakozuna&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Zenodo Record: 19120414&lt;/p&gt;

&lt;p&gt;DOI: 10.5281/zenodo.19120414&lt;/p&gt;

&lt;p&gt;What is Hakozuna?&lt;br&gt;
Hakozuna is a memory allocator designed for small objects, built upon the Box Theory framework. It is currently split into two specialized lineages:&lt;/p&gt;

&lt;p&gt;hz3: Optimized for local-heavy / low-RSS workloads.&lt;/p&gt;

&lt;p&gt;hz4: Optimized for remote-heavy / high-thread environments.&lt;/p&gt;

&lt;p&gt;What’s New in the M1 Mac Update&lt;br&gt;
The primary goal of this update was to establish a seamless workflow on M1 Mac—encompassing development, observation, and running benchmarks for academic papers.&lt;/p&gt;

&lt;p&gt;Key Improvements:&lt;/p&gt;

&lt;p&gt;Refined Mac Entrypoints: All Mac-specific logic is now consolidated in the mac/ directory.&lt;/p&gt;

&lt;p&gt;Pipeline Separation: Decoupled the Build Lane and Observe Lane for better modularity.&lt;/p&gt;

&lt;p&gt;Streamlined Paper-Suite: You can now run the full suite of benchmarks required for research papers with a single setup.&lt;/p&gt;

&lt;p&gt;Comparative Benchmarking: Integrated mimalloc and tcmalloc into the suite to allow direct performance comparisons against hz3 and hz4.&lt;/p&gt;

&lt;p&gt;Performance Insights: Where it Shines&lt;br&gt;
Testing the paper-suite on Mac revealed clear strengths for each allocator:&lt;/p&gt;

&lt;p&gt;hz3 showed dominant performance in the Larson benchmark.&lt;/p&gt;

&lt;p&gt;hz4 took the lead in MT remote (Multi-threaded remote free) scenarios.&lt;/p&gt;

&lt;p&gt;In Redis-like workloads, the winner shifted depending on the specific workload characteristics.&lt;/p&gt;

&lt;p&gt;Note on mimalloc-bench: In our subset tests, certain malloc-large treatments were flagged as "no-go."&lt;/p&gt;

&lt;p&gt;Segment Registry: For high-remote conditions, we found that slots=32768 yielded better results.&lt;/p&gt;

&lt;p&gt;The Takeaway:&lt;br&gt;
The M1 Mac results reinforce our core philosophy: rather than trying to create a "one-size-fits-all" allocator, partitioning "boxes" based on specific conditions leads to superior efficiency.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
With v3.2, "Mac support" is more than just a port—it is a functional environment ready for rigorous academic benchmarking.&lt;/p&gt;

&lt;p&gt;Summary of Gains:&lt;/p&gt;

&lt;p&gt;Improved DX (Developer Experience) on M1 Mac.&lt;/p&gt;

&lt;p&gt;Automated and reliable comparative benchmarking via paper-suite.&lt;/p&gt;

&lt;p&gt;Clearer functional boundaries between the hz3 and hz4 lineages.&lt;/p&gt;

&lt;p&gt;Next, I plan to utilize this Mac environment to refine the supplementary data and further validate my research for the upcoming paper.&lt;/p&gt;

</description>
      <category>c</category>
      <category>hakozuna</category>
      <category>chatgpt</category>
    </item>
    <item>
      <title>Porting Hakozuna to Windows Native: Lessons from Benchmarking hz3 and hz4 beyond Ubuntu</title>
      <dc:creator>CharmPic</dc:creator>
      <pubDate>Tue, 10 Mar 2026 14:36:09 +0000</pubDate>
      <link>https://dev.to/charmpic/porting-hakozuna-to-windows-native-lessons-from-benchmarking-hz3-and-hz4-beyond-ubuntu-4mfh</link>
      <guid>https://dev.to/charmpic/porting-hakozuna-to-windows-native-lessons-from-benchmarking-hz3-and-hz4-beyond-ubuntu-4mfh</guid>
      <description>&lt;p&gt;The Windows native support for Hakozuna has finally moved past the "it runs" stage to the "measurable and comparable" stage.&lt;/p&gt;

&lt;p&gt;Previously, my allocator research was focused on Ubuntu. The major milestone here is that the entire pipeline—from source builds to application benchmarks—is now fully operational on Windows.&lt;/p&gt;

&lt;p&gt;The TL;DR: hz3 remains incredibly strong on Windows. Meanwhile, while hz4 is functional and reproducible, it hasn't yet consistently outperformed others in real-world application benchmarks on Windows without specific tuning. Investigation is ongoing.&lt;/p&gt;

&lt;p&gt;What’s New?&lt;br&gt;
This update isn't just about successful compilation. I've established a robust foundation for comparative allocator research on Windows:&lt;/p&gt;

&lt;p&gt;Native Comparisons: Capability to benchmark hz3, hz4, mimalloc, tcmalloc, and CRT on Windows.&lt;/p&gt;

&lt;p&gt;Real-world Workloads: Support for not just synthetic benchmarks, but also real-world Redis and memcached-style loads.&lt;/p&gt;

&lt;p&gt;Infrastructure: Organized public runners, documentation, and benchmark summary repositories.&lt;/p&gt;

&lt;p&gt;Publications: Updated both Japanese and English versions of the research paper with Windows-specific appendices.&lt;/p&gt;

&lt;p&gt;Distribution: Updated GitHub Releases, Zenodo, and public PDFs.&lt;/p&gt;

&lt;p&gt;The Challenges of Windows Porting&lt;br&gt;
Porting to Windows was far from a simple "copy-paste" from Linux. The difficulties lay less in the allocator's hot path and more in the surrounding ecosystem:&lt;/p&gt;

&lt;p&gt;Build Toolchains: Significant differences in build boxes and environments.&lt;/p&gt;

&lt;p&gt;Linking Nuances: Handling DLL vs. static link mode variations.&lt;/p&gt;

&lt;p&gt;OS-Specific APIs: Architecting around VirtualAlloc paths.&lt;/p&gt;

&lt;p&gt;Porting Workloads: Bringing memcached, memtier, and Redis into a native Windows environment.&lt;/p&gt;

&lt;p&gt;Fixed Costs: Noticing OS-specific fixed costs that were negligible on Linux but prominent on Windows.&lt;/p&gt;

&lt;p&gt;Interestingly, some design choices and default "knobs" that worked perfectly for hz4 on Ubuntu didn't translate into a winning strategy for Windows application benchmarks. This highlights the fascinating—and exhausting—reality of how an allocator's behavior changes depending on the OS.&lt;/p&gt;

&lt;p&gt;Key Benchmark Findings&lt;br&gt;
While the Ubuntu results remain the primary baseline, the Windows native tests revealed:&lt;/p&gt;

&lt;p&gt;hz3 Dominance: Highly performant in real Redis workloads (balanced, kv_only, list_only, highpipe).&lt;/p&gt;

&lt;p&gt;Workload Sensitivity: In memcached external-client tests, the "winning" allocator shifts depending on the specific workload.&lt;/p&gt;

&lt;p&gt;hz4 Potential: While hz4 shows promise in synthetic benchmarks with specific tuning, it showed mixed signals in real Redis balanced tests.&lt;/p&gt;

&lt;p&gt;Current Verdict:&lt;/p&gt;

&lt;p&gt;Default: Use hz3.&lt;/p&gt;

&lt;p&gt;Research Focus: Use hz4 for remote-heavy and high-thread count scenarios.&lt;/p&gt;

&lt;p&gt;Paper and Release Updates&lt;br&gt;
I've synchronized all assets with this release:&lt;/p&gt;

&lt;p&gt;Updated Japanese &amp;amp; English PDFs.&lt;/p&gt;

&lt;p&gt;Added Windows Native supplemental tables.&lt;/p&gt;

&lt;p&gt;GitHub Release v3.1 &amp;amp; Zenodo v3.1 (with updated DOI).&lt;/p&gt;

&lt;p&gt;Latest papers are available directly in the repo at docs/paper/main_ja.pdf and main_en.pdf.&lt;/p&gt;

&lt;p&gt;Personal Insights&lt;br&gt;
The most intriguing discovery was seeing "boxes" (design components) that were unremarkable on Ubuntu suddenly show significant impact on Windows—and vice versa.&lt;/p&gt;

&lt;p&gt;The gap between "performing well in synthetics" and "winning in real apps" is crucial. It’s a stark reminder that in allocator research, looking "fast" on paper matters far less than proving which workload you actually conquer.&lt;/p&gt;

&lt;p&gt;What’s Next?&lt;br&gt;
"Completion" of Windows support actually means reaching a level of maturity where research can truly begin. Moving forward, I plan to:&lt;/p&gt;

&lt;p&gt;Further optimize hz4 specifically for Windows.&lt;/p&gt;

&lt;p&gt;Refine common profiles and OS-specific configurations for Ubuntu/Windows.&lt;/p&gt;

&lt;p&gt;Improve paper and documentation readability.&lt;/p&gt;

&lt;p&gt;Evolve the "Box Theory" into the next architectural phase.&lt;/p&gt;

&lt;p&gt;If there’s interest, my next posts will dive deeper into:&lt;/p&gt;

&lt;p&gt;Why I separated hz3 and hz4.&lt;/p&gt;

&lt;p&gt;How to design an allocator using Box Theory.&lt;/p&gt;

&lt;p&gt;The technical nuances of what looks different on Windows compared to Linux.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/hakorune/hakozuna" rel="noopener noreferrer"&gt;https://github.com/hakorune/hakozuna&lt;/a&gt;&lt;/p&gt;

</description>
      <category>chatgpt</category>
    </item>
  </channel>
</rss>
