<?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>Forem: 0x90</title>
    <description>The latest articles on Forem by 0x90 (@riccio8).</description>
    <link>https://forem.com/riccio8</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3319526%2Fe8f93b12-45c2-4add-aa29-1ed5ed8322ec.jpeg</url>
      <title>Forem: 0x90</title>
      <link>https://forem.com/riccio8</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/riccio8"/>
    <language>en</language>
    <item>
      <title>Rust's regex under the hood...</title>
      <dc:creator>0x90</dc:creator>
      <pubDate>Fri, 04 Jul 2025 13:53:02 +0000</pubDate>
      <link>https://forem.com/riccio8/rusts-regex-under-the-hood-34ac</link>
      <guid>https://forem.com/riccio8/rusts-regex-under-the-hood-34ac</guid>
      <description>&lt;h2&gt;
  
  
  Why should you use regex
&lt;/h2&gt;

&lt;p&gt;A regular expression (regex) is a sequence of symbols that identifies a set of strings, numbers, or other characters. They are used for pattern matching and for verifying data&lt;/p&gt;




&lt;p&gt;Regular expressions are powerful — and dangerous. In most languages, they can lead to unpredictable performance, surprising behavior, or catastrophic backtracking #d1.&lt;/p&gt;

&lt;p&gt;Rust's &lt;code&gt;regex&lt;/code&gt; crate is different. It's designed with safety and speed in mind. But how? What makes it so fast? And how should you write your regex patterns to stay in the fast lane?&lt;/p&gt;

&lt;p&gt;In this post, we'll dig into how Rust handles regular expressions under the hood, how to write efficient patterns, and when things can go wrong (yes, even in Rust).&lt;/p&gt;




&lt;h3&gt;
  
  
  Key design choices:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No backtracking engine&lt;/li&gt;
&lt;li&gt;Compiled to finite automata (NFA/DFA)&lt;/li&gt;
&lt;li&gt;Safe by default: patterns that could cause catastrophic backtracking are &lt;strong&gt;impossible&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📚 Docs: &lt;a href="https://docs.rs/regex/latest/regex/" rel="noopener noreferrer"&gt;regex&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Regex Compilation and Execution Model in Rust
&lt;/h2&gt;

&lt;p&gt;Rust transforms your regex into a sequence of optimized search structures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compilation pipeline:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Parse&lt;/strong&gt; the pattern into an AST&lt;/li&gt;
&lt;li&gt;Convert it into a &lt;strong&gt;Thompson NFA&lt;/strong&gt; (efficient, small-memory execution model)&lt;/li&gt;
&lt;li&gt;Optionally compile into a &lt;strong&gt;lazy DFA&lt;/strong&gt; at runtime (fast, but memory-hungry)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The engine dynamically decides which to use depending on the input and pattern.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lazy DFA:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Built incrementally as needed&lt;/li&gt;
&lt;li&gt;Extremely fast matching (no backtracking)&lt;/li&gt;
&lt;li&gt;May allocate more memory if input is complex&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Theory reference: &lt;a href="https://github.com/rust-lang/regex/blob/master/README.md#implementation" rel="noopener noreferrer"&gt;Regex crate internals – GitHub&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Writing Efficient Regex Patterns
&lt;/h2&gt;

&lt;p&gt;Even with a smart engine, &lt;strong&gt;writing good regex matters&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Best practices:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Prefer &lt;strong&gt;explicit character classes&lt;/strong&gt; over overly broad wildcards:

&lt;ul&gt;
&lt;li&gt;Good: &lt;code&gt;[a-zA-Z0-9_]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Avoid: &lt;code&gt;.*&lt;/code&gt; or &lt;code&gt;.+&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Use &lt;strong&gt;non-greedy quantifiers&lt;/strong&gt; when needed (&lt;code&gt;*?&lt;/code&gt;, &lt;code&gt;+?&lt;/code&gt;)&lt;/li&gt;

&lt;li&gt;Avoid ambiguous alternations: &lt;code&gt;foo|foobar&lt;/code&gt; is slower than &lt;code&gt;foobar|foo&lt;/code&gt;
&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Things to avoid:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Nested quantifiers: &lt;code&gt;.*.*&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Redundant groups: &lt;code&gt;((abc))&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Expecting look-around/backreferences (unsupported)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  RegexSet: When You Have Many Patterns
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.rs/regex/latest/regex/struct.RegexSet.html" rel="noopener noreferrer"&gt;&lt;code&gt;RegexSet&lt;/code&gt;&lt;/a&gt; allows you to &lt;strong&gt;match against many regexes simultaneously&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of testing one-by-one, &lt;code&gt;RegexSet&lt;/code&gt; compiles all regexes into a &lt;strong&gt;single DFA&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example use cases:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Firewall filters&lt;/li&gt;
&lt;li&gt;Log file scanners&lt;/li&gt;
&lt;li&gt;Search engines&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advantages:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fast matching on large pattern sets&lt;/li&gt;
&lt;li&gt;All matches evaluated in a single pass&lt;/li&gt;
&lt;li&gt;Avoids allocation and recompilation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Sample
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;RegexSet&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;RegexSet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="s"&gt;r"foo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;r"bar"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;r"baz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="nf"&gt;.matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"bar"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matches&lt;/span&gt;&lt;span class="nf"&gt;.matched&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// bar is at index 1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Regex Overhead: Compile-Time vs Runtime
&lt;/h2&gt;

&lt;p&gt;Calling &lt;code&gt;Regex::new()&lt;/code&gt; compiles the regex pattern at &lt;strong&gt;runtime&lt;/strong&gt; — this is fast, but not free.&lt;/p&gt;

&lt;h3&gt;
  
  
  Costs:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Compilation allocates memory and builds the NFA/DFA&lt;/li&gt;
&lt;li&gt;Doing this inside a loop or hot path is a &lt;strong&gt;performance killer&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Best practices:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;a href="https://docs.rs/lazy_static/" rel="noopener noreferrer"&gt;&lt;code&gt;lazy_static&lt;/code&gt;&lt;/a&gt; or &lt;a href="https://docs.rs/once_cell/" rel="noopener noreferrer"&gt;&lt;code&gt;once_cell&lt;/code&gt;&lt;/a&gt; to compile once and reuse:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Regex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;once_cell&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Lazy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;RE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Lazy&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Regex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Lazy&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(||&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;Regex&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r"^\d{4}-\d{2}-\d{2}$"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Grouping and Captures in Rust Regex
&lt;/h2&gt;

&lt;p&gt;Rust's regex engine supports &lt;strong&gt;capturing groups&lt;/strong&gt; and &lt;strong&gt;non-capturing groups&lt;/strong&gt;, but &lt;strong&gt;not backreferences&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Basic Capturing Groups
&lt;/h3&gt;

&lt;p&gt;Capturing groups let you extract parts of a match.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Regex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Regex&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r"(\d{4})-(\d{2})-(\d{2})"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;caps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="nf"&gt;.captures&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2025-07-04"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;caps&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"2025-07-04"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// full match&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;caps&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"2025"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// first group&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;caps&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"07"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;         &lt;span class="c1"&gt;// second group&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;caps&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"04"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;         &lt;span class="c1"&gt;// third group&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also name your groups:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Regex&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r"(?P&amp;lt;year&amp;gt;\d{4})-(?P&amp;lt;month&amp;gt;\d{2})-(?P&amp;lt;day&amp;gt;\d{2})"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;caps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="nf"&gt;.captures&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2025-07-04"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;caps&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"2025"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;caps&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"month"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"07"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;caps&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"day"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"04"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Docs: &lt;a href="https://docs.rs/regex/latest/regex/struct.Regex.html#method.captures" rel="noopener noreferrer"&gt;Regex::captures&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Non-Capturing Groups
&lt;/h3&gt;

&lt;p&gt;Non-capturing groups don't save the match — they’re for grouping logic only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Regex&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r"(?:cat|dog)s?"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="nf"&gt;.is_match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cats"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;(?:...)&lt;/code&gt; instead of &lt;code&gt;(...)&lt;/code&gt; when you don't need to capture — this can &lt;strong&gt;improve performance&lt;/strong&gt; slightly.&lt;/p&gt;




&lt;h3&gt;
  
  
  No Backreferences, No Recursion
&lt;/h3&gt;

&lt;p&gt;Rust’s regex engine &lt;strong&gt;does not support&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Backreferences (like &lt;code&gt;\1&lt;/code&gt;, &lt;code&gt;\k&amp;lt;name&amp;gt;&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Recursion (&lt;code&gt;(?R)&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lookahead/lookbehind assertions&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Because the engine avoids features that &lt;strong&gt;require backtracking&lt;/strong&gt;, to guarantee &lt;strong&gt;linear-time execution&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example (NOT supported):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;     &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;invalid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;backreference&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;allowed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Using case
&lt;/h2&gt;

&lt;p&gt;In one of my latest projects, I needed to send a request to an apache http server , which returned the HTTP response headers using &lt;a href="https://curl.se/docs/manpage.html#-I" rel="noopener noreferrer"&gt;curl -I&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;An example of the returned information:

HTTP/1.1 200 OK

Date: Mon, 21 Apr 2025 09:47:53 GMT

Server: Apache/2.4.37 (AlmaLinux) OpenSSL/1.1.1k mod_auth_gssapi/1.6.1

Last-Modified: Fri, 07 Jan 2022 03:05:20 GMT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;My goal was to find the version, such as &lt;code&gt;Apache/2.4.37&lt;/code&gt;, so I wrote this regex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;server_str&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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;Z&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;?&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;z&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;*/&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="err"&gt;\.\&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nf"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;infos&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s"&gt;"gm
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break it down:&lt;/p&gt;

&lt;p&gt;It matches the Server: HTTP header and extracts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;server_str - the literal prefix "Server: "&lt;/li&gt;
&lt;li&gt;version - the first server name/version, like Apache/2.4.37&lt;/li&gt;
&lt;li&gt;infos - everything else after that (OS, modules, etc.)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Quick part-by-part:
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Captures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;(?P&amp;lt;server_str&amp;gt;Server:\s*)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;"Server: "&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;(?P&amp;lt;version&amp;gt;[A-Z]?[a-z]*/\d+\.\d+(?:\.\d+)?)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Apache/2.4.37&lt;/code&gt;, &lt;code&gt;nginx/1.23&lt;/code&gt;, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A space separating version/info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;(?P&amp;lt;infos&amp;gt;.*)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The rest: &lt;code&gt;(AlmaLinux) OpenSSL...&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So it will return 3 named groups:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;server_str&lt;/code&gt;: &lt;code&gt;"Server: "&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;version&lt;/code&gt;: &lt;code&gt;"Apache/2.4.37"&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;infos&lt;/code&gt;: &lt;code&gt;"(AlmaLinux) OpenSSL/1.1.1k mod_auth_gssapi/1.6.1"&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Practicing
&lt;/h3&gt;

&lt;p&gt;If you want to practice &lt;a href="https://regex101.com/" rel="noopener noreferrer"&gt;regex101&lt;/a&gt; is really useful, you can see time, performance, test unit make it for various languages and a lot more...&lt;/p&gt;




&lt;h3&gt;
  
  
  Definitions
&lt;/h3&gt;

&lt;h1&gt;
  
  
  d1 Catastrophic backtracking happens when certain regex patterns cause exponential time complexity due to nested quantifiers — Rust avoids this by design.
&lt;/h1&gt;




&lt;p&gt;&lt;code&gt;💡 any particular request?&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ☕ Was this helpful?
&lt;/h2&gt;

&lt;p&gt;Treat me to a coffee on &lt;a href="https://ko-fi.com/riccardoadami" rel="noopener noreferrer"&gt;Ko-fi&lt;/a&gt; &lt;a href="https://ko-fi.com/riccardoadami" rel="noopener noreferrer"&gt;https://ko-fi.com/riccardoadami&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>rust</category>
      <category>regex</category>
    </item>
    <item>
      <title>Sled, the Fast and Lightweight Rust Database</title>
      <dc:creator>0x90</dc:creator>
      <pubDate>Fri, 04 Jul 2025 09:44:27 +0000</pubDate>
      <link>https://forem.com/riccio8/sled-the-fast-and-lightweight-rust-database-5fjd</link>
      <guid>https://forem.com/riccio8/sled-the-fast-and-lightweight-rust-database-5fjd</guid>
      <description>&lt;h2&gt;
  
  
  Reliable storage with minimal footprint, tailored for Rust developers
&lt;/h2&gt;




&lt;h3&gt;
  
  
  Sled vs SQL vs Other Rust DB Crates (RocksDB, SeaORM, Rbatis)
&lt;/h3&gt;




&lt;p&gt;&lt;em&gt;Recently, I needed to integrate a &lt;strong&gt;database&lt;/strong&gt; into a Rust application. Exploring the ecosystem, I encountered several options: from traditional &lt;strong&gt;SQL-based crates&lt;/strong&gt; like _Diesel&lt;/em&gt; and &lt;em&gt;SQLx&lt;/em&gt;, to embedded key-value stores such as &lt;strong&gt;RocksDB&lt;/strong&gt;, and more lightweight solutions like &lt;strong&gt;Sled&lt;/strong&gt;. Each option offers different trade-offs in terms of &lt;strong&gt;performance&lt;/strong&gt;, &lt;em&gt;ease of use&lt;/em&gt;, &lt;strong&gt;scalability&lt;/strong&gt;, and &lt;strong&gt;flexibility&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;After testing and researching, I realized why &lt;strong&gt;Sled&lt;/strong&gt; stands out for &lt;em&gt;embedded&lt;/em&gt;, &lt;strong&gt;high-performance&lt;/strong&gt;, and &lt;strong&gt;safe data storage&lt;/strong&gt; in Rust applications. Below is a comparison of &lt;strong&gt;Sled&lt;/strong&gt; against other common Rust database crates to help clarify the differences and why &lt;a href="https://docs.rs/sled/latest/sled/" rel="noopener noreferrer"&gt;&lt;strong&gt;Sled&lt;/strong&gt;&lt;/a&gt; could be the ideal choice depending on your project needs. &lt;/p&gt;

&lt;p&gt;Sled guarantees &lt;a href="https://github.com/spacejam/sled/blob/main/SAFETY.md" rel="noopener noreferrer"&gt;crash-safety&lt;/a&gt; by using a lock-free, append-only log structure and supports&lt;a href="https://docs.rs/sled/latest/sled/struct.Batch.html" rel="noopener noreferrer"&gt; atomic batch operations&lt;/a&gt;, making it ideal for concurrent embedded use&lt;/p&gt;




&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Sled&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;SQL-based Crates (Diesel, SQLx)&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Other Rust DB Crates (RocksDB, SeaORM, Rbatis)&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High for embedded use; optimized for fast writes and reads&lt;/td&gt;
&lt;td&gt;Depends on DB backend (Postgres, SQLite), generally it's good&lt;/td&gt;
&lt;td&gt;Varies: RocksDB is very fast for key-value, ORM layers add overhead&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Speed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Very fast in-memory and disk-based operations&lt;/td&gt;
&lt;td&gt;Moderate to fast, depends on SQL backend and query complexity&lt;/td&gt;
&lt;td&gt;RocksDB fast for key-value, ORMs slower due to abstraction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Safety&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Memory safe, leverages Rust ownership; crash-safe design&lt;/td&gt;
&lt;td&gt;Depends on backend; Rust crates provide compile-time query safety&lt;/td&gt;
&lt;td&gt;Varies: RocksDB bindings safe but lower-level; ORMs type-safe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Designed for embedded/single-node; not distributed&lt;/td&gt;
&lt;td&gt;Scales well with DB backend (e.g., Postgres scales well)&lt;/td&gt;
&lt;td&gt;RocksDB scales for local data; ORM scalability depends on backend&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Size/Weight&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Very lightweight (~1 MB crate size); minimal dependencies&lt;/td&gt;
&lt;td&gt;Heavier; depends on features and SQL backend libraries&lt;/td&gt;
&lt;td&gt;RocksDB larger due to C++ dependency; ORMs add abstraction layers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Flexibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Key-value store, no SQL, supports trees and complex data structures&lt;/td&gt;
&lt;td&gt;Full SQL support, complex queries, joins&lt;/td&gt;
&lt;td&gt;Varies: RocksDB key-value; ORMs offer flexible schema and querying&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ease of Use&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Simple API for embedded use, less boilerplate&lt;/td&gt;
&lt;td&gt;Steeper learning curve; need to understand SQL and ORM paradigms&lt;/td&gt;
&lt;td&gt;Varies: RocksDB lower-level, ORMs easier for relational models&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Concurrency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Lock-free design, supports concurrent reads/writes&lt;/td&gt;
&lt;td&gt;Depends on backend and crate support&lt;/td&gt;
&lt;td&gt;RocksDB supports concurrent access; ORMs depend on DB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Use Case&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Embedded apps, local storage, fast persistent KV store&lt;/td&gt;
&lt;td&gt;Web apps, complex querying, relational DB needs&lt;/td&gt;
&lt;td&gt;Embedded key-value, ORM abstraction for relational DBs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Maturity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Actively developed, modern Rust idioms&lt;/td&gt;
&lt;td&gt;Mature ecosystems (Diesel, SQLx widely used)&lt;/td&gt;
&lt;td&gt;Varies widely; RocksDB bindings stable, some ORMs newer&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;p&gt;Here’s a simple example showing how easy it is to open a &lt;strong&gt;DB&lt;/strong&gt;, and &lt;strong&gt;read&lt;/strong&gt;/&lt;strong&gt;write&lt;/strong&gt; &lt;em&gt;data&lt;/em&gt; using &lt;em&gt;Sled&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;sled&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;sled&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;sled&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"my_db"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;b"key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;b"value"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;b"key"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Got: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, a &lt;em&gt;SQL&lt;/em&gt; example from the &lt;a href="https://github.com/launchbadge/sqlx?tab=readme-ov-file#quickstart" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt; looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;PgPoolOptions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// use sqlx::mysql::MySqlPoolOptions;&lt;/span&gt;
&lt;span class="c1"&gt;// etc.&lt;/span&gt;

&lt;span class="nd"&gt;#[async_std::main]&lt;/span&gt; &lt;span class="c1"&gt;// Requires the `attributes` feature of `async-std`&lt;/span&gt;
&lt;span class="c1"&gt;// or #[tokio::main]&lt;/span&gt;
&lt;span class="c1"&gt;// or #[actix_web::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create a connection pool&lt;/span&gt;
    &lt;span class="c1"&gt;//  for MySQL/MariaDB, use MySqlPoolOptions::new()&lt;/span&gt;
    &lt;span class="c1"&gt;//  for SQLite, use SqlitePoolOptions::new()&lt;/span&gt;
    &lt;span class="c1"&gt;//  etc.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;PgPoolOptions&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.max_connections&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"postgres://postgres:password@localhost/test"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Make a simple query to return the given parameter (use a question mark `?` instead of `$1` for MySQL/MariaDB)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;i64&lt;/span&gt;&lt;span class="p"&gt;,)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;query_as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT $1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;150_i64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.fetch_one&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, it requires more configuration and async functions.&lt;/p&gt;




&lt;h3&gt;
  
  
  A direct comparison between sqlx and sled
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;SQLx&lt;/th&gt;
&lt;th&gt;Sled&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Async support&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SQL queries&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Embedded use&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Type safety&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scalability&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ease of use&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weight&lt;/td&gt;
&lt;td&gt;❌ (heavier, async &amp;amp; DB drivers)&lt;/td&gt;
&lt;td&gt;✅ (lightweight, minimal dependencies)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  When (and When Not) to Use Sled
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;When to use Sled:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You need a &lt;strong&gt;fast, embedded key-value store&lt;/strong&gt; for local storage in Rust applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your project requires &lt;strong&gt;crash-safe, concurrent data access&lt;/strong&gt; without complex setup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You want a &lt;strong&gt;lightweight, minimal-dependency database&lt;/strong&gt; that’s easy to integrate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your application doesn’t require SQL queries or relational data modeling.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You’re building &lt;strong&gt;embedded systems, desktop apps, or small services&lt;/strong&gt; with local persistence.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When not to use Sled:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You need &lt;strong&gt;full SQL support&lt;/strong&gt; with complex queries, joins, and transactions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your application requires a &lt;strong&gt;distributed or scalable multi-node database&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You want to leverage existing &lt;strong&gt;relational database backends&lt;/strong&gt; like Postgres or MySQL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You’re working in a &lt;strong&gt;no_std or bare-metal embedded environment&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your project demands extensive &lt;strong&gt;ORM features or schema migrations&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  To summarize
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sled&lt;/strong&gt; is a powerful option when you need &lt;strong&gt;reliable&lt;/strong&gt;, &lt;strong&gt;lightweight&lt;/strong&gt;, and &lt;strong&gt;high-performance&lt;/strong&gt; local storage for Rust applications. It shines in scenarios where &lt;strong&gt;simplicity, speed&lt;/strong&gt;, and &lt;strong&gt;safety&lt;/strong&gt; matter more than SQL features or scalability. If your project doesn't need relational models or complex queries, sled might be the perfect tool for the job.&lt;/p&gt;




&lt;h3&gt;
  
  
  Link
&lt;/h3&gt;

&lt;p&gt;You can find other info at &lt;a href="https://github.com/spacejam/sled" rel="noopener noreferrer"&gt;official GitHub page&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;💡 Other cool stuff?&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ☕ Was this helpful?
&lt;/h2&gt;

&lt;p&gt;Treat me to a coffee on Ko-fi &lt;a href="https://ko-fi.com/riccardoadami" rel="noopener noreferrer"&gt;https://ko-fi.com/riccardoadami&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ko-fi.com/M4M31HDLY8" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.ko-fi.com%2Fcdn%2Fkofi5.png%3Fv%3D6" alt="Buy Me a Coffee at ko-fi.com" width="580" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>rust</category>
      <category>database</category>
      <category>performance</category>
    </item>
    <item>
      <title>Speed Up Rust Code Easily with Rayon</title>
      <dc:creator>0x90</dc:creator>
      <pubDate>Thu, 03 Jul 2025 15:20:38 +0000</pubDate>
      <link>https://forem.com/riccio8/speed-up-rust-code-easily-with-rayon-39gn</link>
      <guid>https://forem.com/riccio8/speed-up-rust-code-easily-with-rayon-39gn</guid>
      <description>&lt;h2&gt;
  
  
  Maximize Rust’s Speed: Achieve Smooth Parallelism Using Rayon
&lt;/h2&gt;




&lt;h2&gt;
  
  
  Why Performance Is Hard
&lt;/h2&gt;

&lt;p&gt;I wanted to speed things up in Rust and let's be honest, &lt;em&gt;threads are one of the best tools to improve performance in Rust&lt;/em&gt;.. But using the Tokio crate can be quite unintuitive and difficult to use, all those await and features... &lt;/p&gt;

&lt;p&gt;Here's where &lt;a href="https://docs.rs/rayon/latest/rayon/index.html" rel="noopener noreferrer"&gt;rayon&lt;/a&gt; helps us, allows us to parallelize tasks without having to think about threads. It's simple to use, fast, lightweight, and just works.&lt;/p&gt;




&lt;h3&gt;
  
  
  A simple definition
&lt;/h3&gt;

&lt;p&gt;Rayon is a library that helps you run code in parallel, making it easy to turn slow, step-by-step computations into faster ones that use multiple CPU cores.&lt;/p&gt;

&lt;p&gt;It's a small and easy-to-use tool that lets you add parallelism. It makes sure your code runs safely without data races, and it only uses parallelism when it makes sense, depending on the amount of work at runtime.&lt;/p&gt;

&lt;p&gt;For example, we can simply turn this line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="nf"&gt;.do_something&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;rayon&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="nf"&gt;.par_iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="nf"&gt;.do_something&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Using the &lt;a href="https://docs.rs/rayon/latest/rayon/prelude/index.html" rel="noopener noreferrer"&gt;prelude&lt;/a&gt; is the easiest way to do parallelism using rayon in rust.&lt;/p&gt;




&lt;h2&gt;
  
  
  Let's break down performance
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Without rayon
&lt;/h3&gt;

&lt;p&gt;I ran the following code which iterates from 1 to 1,000,000, computes the cube (&lt;code&gt;x.pow(3)&lt;/code&gt;) and the square (&lt;code&gt;x.pow(2)&lt;/code&gt;) of each number, takes the remainder of both results using modulo &lt;code&gt;97,531&lt;/code&gt;, then sums those two remainders. I ran it using &lt;code&gt;cargo run&lt;/code&gt; without any optimization:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- `Finished dev profile [unoptimized + debuginfo] target(s) in 0.86s 
-  `Running target\debug\ry.exe 
- `2, 12, 36, 80, 150, 252, 392, 576, 810, 1100`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;These are the CPU specs:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. CPU Name: Intel(R) microarchitecture code named Alderlake-S
2. Frequency: 2.5 GHz
3. Logical CPU Count: 12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;1_000_000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="nf"&gt;.pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;97_531&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="nf"&gt;.pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;97_531&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I measured performance using Intel Vtune profiler and we can see that without using rayon it needs 0.041s using 1 single thread&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.amazonaws.com%2Fuploads%2Farticles%2Fscmvlrqzispqzbi60mw6.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.amazonaws.com%2Fuploads%2Farticles%2Fscmvlrqzispqzbi60mw6.png" alt="profile0" width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and the function which needs more time is the main, because we iterate, calculate and collect the result&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.amazonaws.com%2Fuploads%2Farticles%2Fyw68zjfx3rt7plh243su.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.amazonaws.com%2Fuploads%2Farticles%2Fyw68zjfx3rt7plh243su.png" alt="profile1" width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  With rayon
&lt;/h3&gt;

&lt;p&gt;The computation level is the same as before, but this time we use rayon:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;rayon&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;1_000_000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="nf"&gt;.par_iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="nf"&gt;.pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;97_531&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="nf"&gt;.pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;97_531&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;adding &lt;code&gt;rayon = "1.10.0"&lt;/code&gt; to your Cargo.toml dependencies&lt;/p&gt;

&lt;p&gt;I compiled without optimizations: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Finished dev profile [unoptimized + debuginfo] target(s) in 0.02s
    - Running target\debug\ry.exe`
- [2, 12, 36, 80, 150, 252, 392, 576, 810, 1100]`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Already now we can see that the program ran in 0.02 seconds, compared to 0.86 seconds without Rayon, but let's see in detail:&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.amazonaws.com%2Fuploads%2Farticles%2Fhpnyiobyaakmonwkt9uk.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.amazonaws.com%2Fuploads%2Farticles%2Fhpnyiobyaakmonwkt9uk.png" alt="profile2" width="800" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, we can see it uses 8 threads instead of just one&lt;/li&gt;
&lt;li&gt;We see that it took 0.029 seconds instead of 0.041s&lt;/li&gt;
&lt;li&gt;CPU status is constantly in idle mode instead of poor as before&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As before all the effective time is used by one single function which is the last called &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.amazonaws.com%2Fuploads%2Farticles%2F3it0b52i1sd8g0ws9xdt.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.amazonaws.com%2Fuploads%2Farticles%2F3it0b52i1sd8g0ws9xdt.png" alt="profile3" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  When (and When Not) to Use Rayon
&lt;/h2&gt;

&lt;p&gt;The ideal use cases are &lt;em&gt;CPU-bound work, large datasets, pure functions, sorting, etc.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Instead for &lt;em&gt;small workloads,  shared mutable state or I/O-heavy tasks&lt;/em&gt; it's better to use the &lt;a href="https://docs.rs/tokio/latest/tokio/" rel="noopener noreferrer"&gt;Tokio&lt;/a&gt; runtime if you really need it. The &lt;a href="https://docs.rs/tokio/latest/tokio/#modules" rel="noopener noreferrer"&gt;Tokio module&lt;/a&gt; supports &lt;code&gt;fs, time, command execution, net&lt;/code&gt; and a lot more using multithreading, but that's another topic I'll write about...&lt;/p&gt;




&lt;h3&gt;
  
  
  Other stuff Rayon does
&lt;/h3&gt;

&lt;p&gt;Beyond &lt;code&gt;.map&lt;/code&gt; and &lt;code&gt;.par_iter&lt;/code&gt; Rayon also includes &lt;code&gt;.filter()&lt;/code&gt;, &lt;code&gt;.reduce()&lt;/code&gt;, &lt;code&gt;.for_each()&lt;/code&gt;, &lt;code&gt;join()&lt;/code&gt; for parallel sorting&lt;/p&gt;




&lt;h2&gt;
  
  
  To sum up
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Rayon&lt;/code&gt; isn't always the best choice. Still, it's a &lt;strong&gt;smart and safe way&lt;/strong&gt; to add parallelism. It helps you &lt;strong&gt;scale workloads with minimal code changes&lt;/strong&gt;, making it a solid choice for performance-critical applications.&lt;/p&gt;




&lt;p&gt;&lt;code&gt;💡 Got another crate in mind?&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ☕ Was this helpful?
&lt;/h2&gt;

&lt;p&gt;Treat me to a coffee on Ko-fi &lt;a href="https://ko-fi.com/riccardoadami" rel="noopener noreferrer"&gt;https://ko-fi.com/riccardoadami&lt;/a&gt;&lt;/p&gt;

</description>
      <category>performance</category>
      <category>rust</category>
      <category>multithreading</category>
      <category>profiling</category>
    </item>
    <item>
      <title>Zeroize: The Tiny and Memory-Safe Rust Crate</title>
      <dc:creator>0x90</dc:creator>
      <pubDate>Thu, 03 Jul 2025 12:44:01 +0000</pubDate>
      <link>https://forem.com/riccio8/zeroize-the-tiny-and-memory-safe-rust-crate-1kff</link>
      <guid>https://forem.com/riccio8/zeroize-the-tiny-and-memory-safe-rust-crate-1kff</guid>
      <description>&lt;h2&gt;
  
  
  Sensitive Data in Memory: A Hidden Threat
&lt;/h2&gt;

&lt;p&gt;In a secure environment, &lt;strong&gt;one of the most overlooked threats is the presence of sensitive data in memory&lt;/strong&gt;, such as passwords, tokens, cryptographic keys, or card numbers.&lt;/p&gt;

&lt;p&gt;Even when using Rust, where we emphasize ownership and thread safety, there's another crucial question to consider:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What remains in the heap or stack after we no longer need it?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Memory Zeroing Matters
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.rs/zeroize/latest/zeroize/" rel="noopener noreferrer"&gt;Zeroize&lt;/a&gt; helps us address this. It’s a &lt;strong&gt;lightweight&lt;/strong&gt; but &lt;strong&gt;powerful&lt;/strong&gt; crate that allows us to &lt;em&gt;&lt;strong&gt;zero out&lt;/strong&gt;&lt;/em&gt; memory securely and efficiently.&lt;/p&gt;

&lt;p&gt;Imagine this scenario:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Your program reads a password from user input&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It uses it for authentication or to decrypt a file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The variable goes out of scope and Rust "cleans it up"... &lt;strong&gt;right?&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not quite. &lt;strong&gt;Rust does not guarantee that memory will be overwritten.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;So your password might remain in memory, &lt;em&gt;in plain text&lt;/em&gt;, until it's overwritten by something else. In the case of a &lt;em&gt;memory dump&lt;/em&gt; or &lt;em&gt;cold boot attack&lt;/em&gt;, it could be exposed.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Can You Do About It?
&lt;/h2&gt;

&lt;p&gt;That’s where &lt;code&gt;Zeroize&lt;/code&gt; comes in. It lets you explicitly clear memory when you're done using sensitive data.&lt;br&gt;&lt;br&gt;
Instead of relying on the runtime or assuming safety, you take control. &lt;/p&gt;

&lt;p&gt;It provides a trait &lt;code&gt;Zeroize&lt;/code&gt; which can be derive or implemented manually for your types. &lt;/p&gt;

&lt;p&gt;Using it is literally one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;zeroize&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Zeroize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hunter2"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Use it for authentication or anything else&lt;/span&gt;

     &lt;span class="c1"&gt;// now clean memory&lt;/span&gt;
    &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="nf"&gt;.zeroize&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last line will overwrite the contents of the string with &lt;strong&gt;zero&lt;/strong&gt;. If you use other types like &lt;code&gt;Vec&amp;lt;u8&amp;gt;&lt;/code&gt; it will work in the same way&lt;/p&gt;

&lt;h3&gt;
  
  
  Automate the process
&lt;/h3&gt;

&lt;p&gt;If you want to automate everything, you can wrap your data with Zeroizing, which will automatically reset it when it goes out of scope:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;zeroize&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Zeroizing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Zeroizing&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hunter2"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="c1"&gt;// No need to call zeroize, auto-zero on drop&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy, elegant, secure. It adds almost no overhead to your final binary&lt;/p&gt;

&lt;h3&gt;
  
  
  When should you use it?
&lt;/h3&gt;

&lt;p&gt;Every time you handle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Password&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Auth token (eg. JWT, OAuth)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Encryption keys (AES, ChaCha20, etc) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Any data that shouldn't live in RAM longer than necessary&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  In synthesis
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Zeroize&lt;/code&gt; is not magic.But &lt;strong&gt;it's a good habit&lt;/strong&gt;. It won't protect you from every attack, but it does make your code &lt;strong&gt;more resilient&lt;/strong&gt;, especially in environments where security ≠ optional (embedded, mobile, backend auth, etc.)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;💡 Do you know any other crate that you'd like to explore? Let me know&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Originally published on my &lt;a href="https://riccio.hashnode.dev/zeroize-the-tiny-and-memory-safe-rust-crate" rel="noopener noreferrer"&gt;Hashnode blog&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ☕ Was this helpful?
&lt;/h2&gt;

&lt;p&gt;Treat me to a coffee on Ko-fi &lt;a href="https://ko-fi.com/riccardoadami" rel="noopener noreferrer"&gt;https://ko-fi.com/riccardoadami&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ko-fi.com/M4M31HDLY8" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.ko-fi.com%2Fcdn%2Fkofi5.png%3Fv%3D6" alt="Buy Me a Coffee at ko-fi.com" width="580" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>rust</category>
      <category>cybersecurity</category>
      <category>security</category>
    </item>
  </channel>
</rss>
