<?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: Masahiro Sugaya</title>
    <description>The latest articles on DEV Community by Masahiro Sugaya (@xsigil).</description>
    <link>https://dev.to/xsigil</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%2F4146051%2F93d74568-b788-41be-aab8-1a193f7c3e6e.png</url>
      <title>DEV Community: Masahiro Sugaya</title>
      <link>https://dev.to/xsigil</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/xsigil"/>
    <language>en</language>
    <item>
      <title>fzgrep: A zero-dependency, OpenMP-parallelized fuzzy line matcher in C</title>
      <dc:creator>Masahiro Sugaya</dc:creator>
      <pubDate>Sun, 27 Sep 2026 22:01:45 +0000</pubDate>
      <link>https://dev.to/xsigil/fzgrep-a-zero-dependency-openmp-parallelized-fuzzy-line-matcher-in-c-57fg</link>
      <guid>https://dev.to/xsigil/fzgrep-a-zero-dependency-openmp-parallelized-fuzzy-line-matcher-in-c-57fg</guid>
      <description>&lt;p&gt;I built &lt;strong&gt;&lt;a href="https://github.com/xsigil/fzgrep" rel="noopener noreferrer"&gt;fzgrep&lt;/a&gt;&lt;/strong&gt;, a lightweight, OpenMP-parallelized fuzzy line matcher written in pure C with zero external runtime dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;In standard UNIX pipelines, filtering text has two well-known extremes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;grep&lt;/code&gt; / &lt;code&gt;ripgrep&lt;/code&gt;&lt;/strong&gt;: Incredibly fast for exact substrings and regex, but completely unforgiving when handling typos or fuzzy criteria.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;fzf&lt;/code&gt;&lt;/strong&gt;: A masterpiece for interactive TUI navigation, but not designed to be dropped headlessly into non-interactive batch pipelines.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I needed something in between: a pipeline-native fuzzy matcher that accepts stdin or files, runs headlessly, and fully utilizes modern multi-core CPUs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture &amp;amp; Design
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Dynamic Single-Row Levenshtein
&lt;/h3&gt;

&lt;p&gt;Instead of allocating a full $O(N \times M)$ distance matrix, &lt;code&gt;fzgrep&lt;/code&gt; computes Levenshtein distance using a dynamic single-row cache ($O(N)$ space complexity).&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Chunk-Based MapReduce via OpenMP
&lt;/h3&gt;

&lt;p&gt;Fuzzy matching on large text streams is computationally heavy. &lt;code&gt;fzgrep&lt;/code&gt; solves this with a chunk-based MapReduce model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The main thread buffers incoming lines into chunks (8,192 lines by default).&lt;/li&gt;
&lt;li&gt;Worker threads parallelize the distance calculations across available CPU cores (configurable with &lt;code&gt;-j&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Results are deterministically aggregated, sorted by similarity score (descending), and tie-broken alphabetically.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Word Match Mode (&lt;code&gt;-w&lt;/code&gt;) and Coordinate Tracking (&lt;code&gt;-n&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Beyond full-line distance checks, &lt;code&gt;fzgrep&lt;/code&gt; can split lines into space-delimited tokens to match against individual words. Combining &lt;code&gt;-w&lt;/code&gt; with &lt;code&gt;-n&lt;/code&gt; emits compiler-friendly coordinates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Word match mode with coordinates &amp;amp; scores&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"hello everyone"&lt;/span&gt; | fzgrep &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; 0.3 &lt;span class="s2"&gt;"eve"&lt;/span&gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0.38    1:7:2:hello everyone

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

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;(Line 1, column 7, word 2)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Example: Typo-Tolerant Pipeline
&lt;/h2&gt;

&lt;p&gt;Filter a large list of symbols or logs with typo tolerance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /usr/share/dict/words | fzgrep &lt;span class="nt"&gt;-j&lt;/span&gt; 8 &lt;span class="nt"&gt;-t&lt;/span&gt; 0.8 &lt;span class="s2"&gt;"algotithm"&lt;/span&gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;algorithm

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

&lt;/div&gt;



&lt;p&gt;Prefixing matches with similarity scores (&lt;code&gt;-s&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"apple&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;application&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;apricot&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;banana"&lt;/span&gt; | fzgrep &lt;span class="nt"&gt;-t&lt;/span&gt; 0.5 &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"appl"&lt;/span&gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0.80    apple
0.57    application

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Source Code &amp;amp; Roadmap
&lt;/h2&gt;

&lt;p&gt;The source code, automated test suite, and prebuilt binaries are available under GPL-2.0 on GitHub:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/xsigil/fzgrep?utm_source=gemini" rel="noopener noreferrer"&gt;https://github.com/xsigil/fzgrep&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I would love to hear feedback from the community:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How would you handle chunk sizing on gigabyte-scale streams?&lt;/li&gt;
&lt;li&gt;Are there specific distance metrics or pruning techniques you'd like to see added?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feel free to check it out, run the tests, and leave your thoughts in the comments!&lt;br&gt;
"""&lt;/p&gt;

</description>
      <category>c</category>
      <category>linux</category>
      <category>cli</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
