<?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: Alex</title>
    <description>The latest articles on DEV Community by Alex (@phpner).</description>
    <link>https://dev.to/phpner</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%2F3421253%2F38019e86-0882-49d9-96f4-99c4eda5f59a.jpeg</url>
      <title>DEV Community: Alex</title>
      <link>https://dev.to/phpner</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/phpner"/>
    <language>en</language>
    <item>
      <title>PHP Profiling: From Problem to Solution (with Metrics)</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Sat, 16 Aug 2025 12:09:39 +0000</pubDate>
      <link>https://dev.to/phpner/php-profiling-from-problem-to-solution-with-metrics-2epf</link>
      <guid>https://dev.to/phpner/php-profiling-from-problem-to-solution-with-metrics-2epf</guid>
      <description>&lt;h2&gt;
  
  
  Initial Scenario
&lt;/h2&gt;

&lt;p&gt;We have a script that processes &lt;strong&gt;200,000 email addresses&lt;/strong&gt;.&lt;br&gt;
It was expected to run fast, but the measurement showed &lt;strong&gt;12.8 seconds&lt;/strong&gt;.&lt;br&gt;
We need to identify what slows it down and speed it up.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1. Capture a Profile
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Xdebug config (CLI):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;zend_extension&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;xdebug&lt;/span&gt;
&lt;span class="py"&gt;xdebug.mode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;profile&lt;/span&gt;
&lt;span class="py"&gt;xdebug.output_dir&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/tmp/xdebug&lt;/span&gt;
&lt;span class="py"&gt;xdebug.start_with_request&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php import_emails.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A file &lt;code&gt;cachegrind.out.*&lt;/code&gt; appears in &lt;code&gt;/tmp/xdebug&lt;/code&gt;.&lt;br&gt;
Open it with &lt;strong&gt;KCachegrind&lt;/strong&gt; (Linux) or &lt;strong&gt;QCachegrind&lt;/strong&gt; (macOS/Windows).&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2. Read the Profile
&lt;/h2&gt;

&lt;p&gt;The profile shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;array_unique&lt;/code&gt; — &lt;strong&gt;42% Self time&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;filter_var&lt;/code&gt; — &lt;strong&gt;35% Inclusive time&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Lots of unnecessary string allocations due to repeated transformations.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Step 3. Optimize Step‑by‑Step
&lt;/h2&gt;

&lt;p&gt;PHP Email Import Optimization — Before vs After&lt;/p&gt;
&lt;h3&gt;
  
  
  1) Remove &lt;code&gt;array_unique&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (expensive: stores all emails, then deduplicates):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$emails&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$rows&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="c1"&gt;// ... other logic ...&lt;/span&gt;
    &lt;span class="nv"&gt;$emails&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// duplicates pile up&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nv"&gt;$emails&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_unique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$emails&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// heavy on time &amp;amp; memory&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (instant dedup with a set-like map):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$rows&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'email'&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="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$set&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;$set&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&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;&lt;em&gt;Metric: 12.8 → 8.5 s, memory: 78 → 56 MB.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2) Fewer string transformations
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (repeated/extra transformations):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$rows&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;$email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;strtolower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// later again (duplicated work):&lt;/span&gt;
    &lt;span class="nv"&gt;$email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;strtolower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$email&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="nv"&gt;$email&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&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;&lt;strong&gt;After (do it once, in the right order):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$rows&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s1"&gt;''&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="nv"&gt;$email&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;$email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;strtolower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// proceed with $email&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Metric: 8.5 → 5.4 s, memory: 56 → 42 MB.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3) Lightweight email validation (optional)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (heavier checks like full RFC/IDN):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$rows&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;strtolower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s1"&gt;''&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="nv"&gt;$email&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&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="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;filter_var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;FILTER_VALIDATE_EMAIL&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (simple format check):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$rows&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;strtolower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s1"&gt;''&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="nv"&gt;$email&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&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="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;preg_match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/^[^\s@]+@[^\s@]+\.[^\s@]+$/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Metric: 5.4 → 2.1 s, memory: 42 → 40 MB.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep &lt;code&gt;filter_var&lt;/code&gt;/IDN if you need strict RFC compliance or internationalized domains.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Memory&lt;/th&gt;
&lt;th&gt;Gain&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Before&lt;/td&gt;
&lt;td&gt;12.8s&lt;/td&gt;
&lt;td&gt;78 MB&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;After step 1&lt;/td&gt;
&lt;td&gt;8.5s&lt;/td&gt;
&lt;td&gt;56 MB&lt;/td&gt;
&lt;td&gt;−4.3s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;After step 2&lt;/td&gt;
&lt;td&gt;5.4s&lt;/td&gt;
&lt;td&gt;42 MB&lt;/td&gt;
&lt;td&gt;−3.1s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;After step 3&lt;/td&gt;
&lt;td&gt;2.1s&lt;/td&gt;
&lt;td&gt;40 MB&lt;/td&gt;
&lt;td&gt;−3.3s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;Without profiling we’d waste time optimizing blindly.&lt;br&gt;
With the profile we see exactly &lt;strong&gt;where&lt;/strong&gt; resources are spent and fix only that.&lt;br&gt;
Result — &lt;strong&gt;6× faster&lt;/strong&gt; and &lt;strong&gt;2× less memory&lt;/strong&gt;.&lt;br&gt;
(the exact numbers may vary depending on your machine)&lt;/p&gt;

&lt;h2&gt;
  
  
  Five Golden Rules of Profiling
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Measure, don’t speculate.&lt;/li&gt;
&lt;li&gt;Compare apples to apples (same data, same setup).&lt;/li&gt;
&lt;li&gt;Hunt down the biggest time-wasters first.&lt;/li&gt;
&lt;li&gt;Fix one thing at a time.&lt;/li&gt;
&lt;li&gt;Trust metrics, not intuition.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Repository
&lt;/h2&gt;

&lt;p&gt;All the code examples used in this article (before/after scripts) are available here: &lt;a href="https://github.com/phpner/php-profiling-example" rel="noopener noreferrer"&gt;https://github.com/phpner/php-profiling-example&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Profiling gives a clear picture of what slows your code.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Lazy Evaluation in PHP: Real‑World Memory Savings with Generators</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Fri, 08 Aug 2025 16:33:47 +0000</pubDate>
      <link>https://dev.to/phpner/lazy-evaluation-in-php-how-generators-and-iterators-save-memory-and-speed-up-code-3529</link>
      <guid>https://dev.to/phpner/lazy-evaluation-in-php-how-generators-and-iterators-save-memory-and-speed-up-code-3529</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Have you ever tried to load a CSV file with a million rows into memory and ended up with something like this?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;PHP&lt;/span&gt; &lt;span class="s"&gt;Fatal&lt;/span&gt; &lt;span class="s"&gt;error:&lt;/span&gt;  &lt;span class="s"&gt;Allowed&lt;/span&gt; &lt;span class="s"&gt;memory&lt;/span&gt; &lt;span class="s"&gt;size&lt;/span&gt; &lt;span class="s"&gt;of&lt;/span&gt; &lt;span class="mi"&gt;134217728&lt;/span&gt; &lt;span class="s"&gt;bytes&lt;/span&gt; &lt;span class="s"&gt;exhausted&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even with a higher &lt;code&gt;memory_limit&lt;/code&gt;, the entire dataset still sits in memory while you process it line by line.&lt;/p&gt;

&lt;p&gt;The solution? &lt;strong&gt;Lazy evaluation&lt;/strong&gt; — a technique where data is generated and processed only when it's actually needed.&lt;br&gt;&lt;br&gt;
In PHP, you can achieve this in two ways: with &lt;strong&gt;generators&lt;/strong&gt; (&lt;code&gt;yield&lt;/code&gt;) and via the &lt;strong&gt;Iterator API&lt;/strong&gt;. Let’s explore both.&lt;/p&gt;
&lt;h2&gt;
  
  
  What Is Lazy Evaluation?
&lt;/h2&gt;

&lt;p&gt;Normally, when you create an array, PHP loads all elements into memory at once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getNumbersArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$count&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nv"&gt;$count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getNumbersArray&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="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$number&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="kc"&gt;PHP_EOL&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;Here, the entire array &lt;code&gt;[1, 2, 3, 4, 5]&lt;/code&gt; is stored in memory.&lt;/p&gt;

&lt;p&gt;Now let’s try a lazy approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getNumbersGenerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$count&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;Generator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nv"&gt;$count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getNumbersGenerator&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="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$number&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="kc"&gt;PHP_EOL&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 key difference: the generator doesn't store everything — it yields one element at a time, as &lt;code&gt;foreach&lt;/code&gt; requests it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading a Huge CSV Without Pain
&lt;/h2&gt;

&lt;p&gt;Imagine you have a &lt;code&gt;data.csv&lt;/code&gt; file that’s 2 GB in size. If you try to load it with &lt;code&gt;file()&lt;/code&gt; or &lt;code&gt;fgetcsv()&lt;/code&gt; into an array, you'll likely run out of memory.&lt;br&gt;&lt;br&gt;
But with a generator, it's easy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;readCsv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$filename&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;Generator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$handle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;fopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'r'&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="nv"&gt;$handle&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RuntimeException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Cannot open file &lt;/span&gt;&lt;span class="nv"&gt;$filename&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;$row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;fgetcsv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$handle&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nv"&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;fclose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$handle&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;readCsv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'data.csv'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Process the row&lt;/span&gt;
    &lt;span class="c1"&gt;// For example: echo implode(', ', $row) . PHP_EOL;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📊 &lt;strong&gt;Memory usage&lt;/strong&gt;: even with a 2 GB CSV, only one row is stored in memory at a time, so usage stays in the kilobytes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmark: Array vs Generator
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$startMemory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;memory_get_usage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nv"&gt;$array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;range&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="mi"&gt;1_000_000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// creates an array with a million numbers&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Array: "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;memory_get_usage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;$startMemory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;" MB
"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;unset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$array&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$startMemory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;memory_get_usage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;bigGenerator&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;Generator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&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="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;bigGenerator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Just iterate&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Generator: "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;memory_get_usage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;$startMemory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;" MB
"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;On my machine:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Array: 120 MB
Generator: 0.5 MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Iterator API
&lt;/h2&gt;

&lt;p&gt;Generators are quick and simple. But sometimes you need &lt;strong&gt;more control&lt;/strong&gt; — preserving state, managing custom keys, or switching data sources dynamically.&lt;br&gt;&lt;br&gt;
That's where the &lt;strong&gt;Iterator API&lt;/strong&gt; comes in.&lt;/p&gt;
&lt;h3&gt;
  
  
  Example: Custom Iterator
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RangeIterator&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Iterator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;rewind&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RangeIterator&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$num&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="kc"&gt;PHP_EOL&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;
  
  
  When to Use What?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Recommended Approach&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Need to stream data on demand&lt;/td&gt;
&lt;td&gt;Generator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Need complex logic or internal state&lt;/td&gt;
&lt;td&gt;Iterator API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reading large files or DB streams&lt;/td&gt;
&lt;td&gt;Generator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multiple iterations with preserved state&lt;/td&gt;
&lt;td&gt;Iterator API&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Real Production Case
&lt;/h2&gt;

&lt;p&gt;We were parsing an automotive sales API that returned &lt;strong&gt;hundreds of thousands&lt;/strong&gt; of records.&lt;br&gt;&lt;br&gt;
Originally, we loaded everything into an array — the script used 1–2 GB of memory.&lt;br&gt;&lt;br&gt;
After switching to a generator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;fetchCars&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;Generator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;apiRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'cars'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'page'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$page&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'items'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$car&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nv"&gt;$car&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nv"&gt;$page&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'items'&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;📉 Memory usage dropped from 2 GB to just 10 MB — with no noticeable change in execution time.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍 For Geeks: How Generators Work Under the Hood
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. A Generator Is an Object
&lt;/h3&gt;

&lt;p&gt;In PHP, a generator is an object of class &lt;code&gt;Generator&lt;/code&gt;, implementing both &lt;code&gt;Iterator&lt;/code&gt; and &lt;code&gt;Traversable&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
It can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;store function state;&lt;/li&gt;
&lt;li&gt;pause execution at &lt;code&gt;yield&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;resume from the same spot.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Execution Flow
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Calling the generator function doesn’t run the code — it returns a &lt;code&gt;Generator&lt;/code&gt; object.&lt;/li&gt;
&lt;li&gt;The first &lt;code&gt;foreach&lt;/code&gt; or &lt;code&gt;current()&lt;/code&gt; call executes until the first &lt;code&gt;yield&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Each &lt;code&gt;yield&lt;/code&gt; pauses execution and returns a value.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;next()&lt;/code&gt; resumes from the paused point.&lt;/li&gt;
&lt;li&gt;When the function ends, the generator is marked as completed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Zend Engine Internals
&lt;/h3&gt;

&lt;p&gt;If you compile a generator function using VLD (Vulcan Logic Disassembler), each &lt;code&gt;yield&lt;/code&gt; corresponds to an instruction that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;saves the call stack;&lt;/li&gt;
&lt;li&gt;stores variable context;&lt;/li&gt;
&lt;li&gt;yields control back to the caller.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Compared to Arrays
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Arrays store &lt;strong&gt;all elements&lt;/strong&gt; in memory at once.&lt;/li&gt;
&lt;li&gt;Generators hold only &lt;strong&gt;the current element&lt;/strong&gt; (&lt;code&gt;zval&lt;/code&gt;) and overwrite it with each step.&lt;/li&gt;
&lt;li&gt;You can process a million elements using just a few hundred kilobytes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Infinite Generator Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;Generator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$num&lt;/span&gt;&lt;span class="p"&gt;)&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="nv"&gt;$num&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$num&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="kc"&gt;PHP_EOL&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;You couldn’t do this with an array — memory would run out quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔗 Source Code
&lt;/h2&gt;

&lt;p&gt;You can try everything yourself — the code used in this article is open source:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/phpner/phpner-php-lazy-evaluation-demo" rel="noopener noreferrer"&gt;github.com/phpner/phpner-php-lazy-evaluation-demo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSV benchmark: array (eager) vs generator (lazy)&lt;/li&gt;
&lt;li&gt;NDJSON stream simulation&lt;/li&gt;
&lt;li&gt;Memory and time profiling&lt;/li&gt;
&lt;li&gt;CLI-friendly tools&lt;/li&gt;
&lt;li&gt;Sample data generator&lt;/li&gt;
&lt;li&gt;PHPUnit tests&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📊 Benchmark results (1,000,001 rows)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Memory used&lt;/th&gt;
&lt;th&gt;Peak diff&lt;/th&gt;
&lt;th&gt;Rows&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Array (eager)&lt;/td&gt;
&lt;td&gt;1.401s&lt;/td&gt;
&lt;td&gt;120 B&lt;/td&gt;
&lt;td&gt;395.92 MB&lt;/td&gt;
&lt;td&gt;1,000,001&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generator&lt;/td&gt;
&lt;td&gt;1.012s&lt;/td&gt;
&lt;td&gt;0 B&lt;/td&gt;
&lt;td&gt;0.00 MB&lt;/td&gt;
&lt;td&gt;1,000,001&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These results show that lazy generators can significantly reduce memory usage when processing large datasets like CSVs.&lt;/p&gt;

&lt;h2&gt;
  
  
  🖼️ Visual results
&lt;/h2&gt;

&lt;p&gt;📈 Peak memory usage:&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%2Fn3irar7mogjag56vjd3d.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%2Fn3irar7mogjag56vjd3d.png" alt="Peak memory" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📉 Execution time:&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%2Fyxufsvem61gztb9yavly.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%2Fyxufsvem61gztb9yavly.png" alt="Execution time" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to fork the repo, try the benchmarks, or adapt it to your own data processing tasks!&lt;/p&gt;

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

&lt;p&gt;✅ Generators and the Iterator API are must-haves for modern PHP development.&lt;br&gt;&lt;br&gt;
They let you process &lt;strong&gt;millions of records&lt;/strong&gt; without running out of memory.&lt;br&gt;&lt;br&gt;
Use generators for simple streaming logic, and Iterator API when you need more control.&lt;/p&gt;

&lt;p&gt;💬 Do you use generators in production? Share your use cases in the comments!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>backenddevelopment</category>
      <category>php</category>
      <category>performance</category>
    </item>
    <item>
      <title>The Hidden Path to Computers — Through the Lens of “Code” by Charles Petzold</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Fri, 08 Aug 2025 08:51:48 +0000</pubDate>
      <link>https://dev.to/phpner/the-hidden-path-to-computers-through-the-lens-of-code-by-charles-petzold-593p</link>
      <guid>https://dev.to/phpner/the-hidden-path-to-computers-through-the-lens-of-code-by-charles-petzold-593p</guid>
      <description>&lt;h1&gt;
  
  
  📖 About the Book
&lt;/h1&gt;

&lt;p&gt;Charles Petzold is an author who managed to explain the complex world of computer technology through compelling storytelling. His book &lt;em&gt;Code: The Hidden Language of Computer Hardware and Software&lt;/em&gt; takes us on a journey from the earliest methods of communication to the modern digital computer — without dry technical jargon, but with real-world examples, metaphors, and historical facts.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Computers are not magic. They are the result of a long human journey that began long before the invention of electronics."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1. How Humans Began to Communicate Information
&lt;/h2&gt;

&lt;p&gt;Petzold begins by showing that people have always had the need to send messages across distances. At first, this meant using signal fires on hills, drums in the jungle, or flags on ships. Each of these methods had limits: in speed, distance, or the number of symbols available.&lt;/p&gt;

&lt;p&gt;Eventually, we arrive at Morse code.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Morse Code: The First “Zeros” and “Ones”
&lt;/h2&gt;

&lt;p&gt;Samuel Morse invented a system of &lt;strong&gt;short (dot)&lt;/strong&gt; and &lt;strong&gt;long (dash)&lt;/strong&gt; electrical signals. It was the first practical digital code — not literally zeros and ones, but conceptually very close: &lt;strong&gt;only two distinct signals&lt;/strong&gt; used in combination to represent any letter or number.&lt;/p&gt;

&lt;h3&gt;
  
  
  📌 Key features:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency&lt;/strong&gt;: The most common letters (like E and T) were assigned the shortest codes.&lt;/li&gt;
&lt;li&gt;Messages were sent by completing or breaking an electrical circuit.&lt;/li&gt;
&lt;li&gt;Telegraph operators could &lt;em&gt;hear&lt;/em&gt; the code in real time and interpret it by ear.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Morse code was the first system to show that any kind of information could be transmitted using just two types of signals.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3. From Signals to Electricity
&lt;/h2&gt;

&lt;p&gt;The telegraph was revolutionary for communication, but it &lt;strong&gt;only transmitted&lt;/strong&gt;, not processed, information.  &lt;/p&gt;

&lt;p&gt;The next leap came with the realization that &lt;strong&gt;electric signals could do work&lt;/strong&gt; — they could control machines, and ultimately, perform logic.&lt;/p&gt;

&lt;p&gt;Here, Petzold introduces &lt;strong&gt;the relay&lt;/strong&gt; — a simple switch that opens or closes in response to electrical current. It too has &lt;strong&gt;two states&lt;/strong&gt;, which fits naturally into &lt;strong&gt;binary logic&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The Binary Number System
&lt;/h2&gt;

&lt;p&gt;For a machine to "understand" anything, it must be able to represent numbers and instructions.&lt;br&gt;&lt;br&gt;
The binary system (0 and 1) turned out to be ideal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;0 = off
&lt;/li&gt;
&lt;li&gt;1 = on
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Historically, the binary number system was described by &lt;strong&gt;Gottfried Wilhelm Leibniz&lt;/strong&gt; in the 17th century. But with the invention of electrical switches, it became practically useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Logic Gates and Circuits
&lt;/h2&gt;

&lt;p&gt;Petzold shows that using relays, you can build basic logic gates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AND&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OR&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NOT&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By combining these, you can construct &lt;strong&gt;any computation&lt;/strong&gt;. This leads to the central insight:  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A computer is essentially a massive network of binary switches arranged in logical combinations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  6. From Mechanical Devices to Electronics
&lt;/h2&gt;

&lt;p&gt;Before relays, there were &lt;strong&gt;mechanical calculators&lt;/strong&gt; — like Charles Babbage’s Analytical Engine. But they were slow, bulky, and unreliable.&lt;/p&gt;

&lt;p&gt;Eventually, &lt;strong&gt;vacuum tubes&lt;/strong&gt; and &lt;strong&gt;transistors&lt;/strong&gt; replaced relays, making computations &lt;strong&gt;faster and more compact&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Encoding Text, Images, and Sound
&lt;/h2&gt;

&lt;p&gt;Once you can handle numbers, you can represent anything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Text&lt;/strong&gt;: through &lt;strong&gt;ASCII&lt;/strong&gt;, where each letter has a unique binary number.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Images&lt;/strong&gt;: grids of black/white pixels, each encoded as 0 or 1.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sound&lt;/strong&gt;: sequences of numbers representing waveform amplitudes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This showed that &lt;strong&gt;all information&lt;/strong&gt; — visual, audio, textual — could be reduced to binary.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Programs and Memory
&lt;/h2&gt;

&lt;p&gt;After machines could store and manipulate binary data, they needed instructions — &lt;strong&gt;programs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Memory began to store both &lt;strong&gt;data and instructions&lt;/strong&gt;, which led to the concept of the &lt;strong&gt;Von Neumann architecture&lt;/strong&gt;, where program and data coexist in the same memory space.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. The Big Realization
&lt;/h2&gt;

&lt;p&gt;By the end of the book, the reader understands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A computer is not a magical box. It’s a machine built from &lt;strong&gt;simple components&lt;/strong&gt; (relays, switches, transistors) that operate on &lt;strong&gt;binary logic&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Complexity arises from &lt;strong&gt;the clever arrangement of simple building blocks&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“A computer is nothing more than a very fast and very obedient idiot doing exactly what we tell it to.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🎯 Why This Book Is Valuable
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It gives you an &lt;strong&gt;intuitive understanding&lt;/strong&gt; of how computers work — without formulas.
&lt;/li&gt;
&lt;li&gt;It shows a clear &lt;strong&gt;historical progression&lt;/strong&gt;:
&lt;em&gt;signal fires → Morse code → relays → transistors → processors&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;After reading it, you begin to see technology as a chain of &lt;strong&gt;brilliant simplifications&lt;/strong&gt;, rather than complexity.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
