<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Heavy on RawCull</title><link>https://rawcull.netlify.app/tags/heavy/</link><description>Recent content in Heavy on RawCull</description><generator>Hugo</generator><language>en</language><lastBuildDate>Thu, 19 Mar 2026 18:31:57 +0100</lastBuildDate><atom:link href="https://rawcull.netlify.app/tags/heavy/index.xml" rel="self" type="application/rss+xml"/><item><title>Synchronous Code</title><link>https://rawcull.netlify.app/blog/2026/02/19/synchronous-code/</link><pubDate>Thu, 19 Feb 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/02/19/synchronous-code/</guid><description>&lt;h1 id="a-guide-to-handling-heavy-synchronous-code-in-swift-concurrency"&gt;A Guide to Handling Heavy Synchronous Code in Swift Concurrency&lt;a class="td-heading-self-link" href="#a-guide-to-handling-heavy-synchronous-code-in-swift-concurrency" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This post explains why CPU-intensive synchronous code (such as image decoding via ImageIO) must be dispatched off the Swift Concurrency thread pool, and shows the correct patterns RawCull uses to do so.&lt;/p&gt;
&lt;h2 id="dispatchqueueglobalqos--qos-levels-compared"&gt;&lt;code&gt;DispatchQueue.global(qos:)&lt;/code&gt; — QoS Levels Compared&lt;a class="td-heading-self-link" href="#dispatchqueueglobalqos--qos-levels-compared" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The key difference is &lt;strong&gt;priority and resource allocation&lt;/strong&gt; by the system.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="userinitiated"&gt;&lt;code&gt;.userInitiated&lt;/code&gt;&lt;a class="td-heading-self-link" href="#userinitiated" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Priority:&lt;/strong&gt; High (just below &lt;code&gt;.userInteractive&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Work the &lt;strong&gt;user directly triggered&lt;/strong&gt; and is actively waiting for — e.g., loading a document they tapped, parsing data to display a screen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Expected duration:&lt;/strong&gt; Near-instantaneous to a few seconds&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;System behavior:&lt;/strong&gt; Gets &lt;strong&gt;more CPU time and higher thread priority&lt;/strong&gt; — the system treats this as urgent&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Energy impact:&lt;/strong&gt; Higher&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="utility"&gt;&lt;code&gt;.utility&lt;/code&gt;&lt;a class="td-heading-self-link" href="#utility" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Priority:&lt;/strong&gt; Low-medium&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Long-running work the user is &lt;strong&gt;aware of but not blocked by&lt;/strong&gt; — e.g., downloading files, importing data, periodic syncs, progress-bar tasks&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Expected duration:&lt;/strong&gt; Seconds to minutes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;System behavior:&lt;/strong&gt; Balanced CPU/energy trade-off; the system &lt;strong&gt;throttles this more aggressively&lt;/strong&gt; under load or low battery&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Energy impact:&lt;/strong&gt; Lower (system may apply energy efficiency optimizations)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="quick-comparison"&gt;Quick Comparison&lt;a class="td-heading-self-link" href="#quick-comparison" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;&lt;code&gt;.userInitiated&lt;/code&gt;&lt;/th&gt;
 &lt;th&gt;&lt;code&gt;.utility&lt;/code&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Priority&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;High&lt;/td&gt;
 &lt;td&gt;Low-medium&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;User waiting?&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Yes, directly&lt;/td&gt;
 &lt;td&gt;Aware but not blocked&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Duration&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&amp;lt; a few seconds&lt;/td&gt;
 &lt;td&gt;Seconds to minutes&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;CPU allocation&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Aggressive&lt;/td&gt;
 &lt;td&gt;Conservative&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Battery impact&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Higher&lt;/td&gt;
 &lt;td&gt;Lower&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Thread pool&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Higher-priority threads&lt;/td&gt;
 &lt;td&gt;Lower-priority threads&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="rule-of-thumb"&gt;Rule of thumb&lt;a class="td-heading-self-link" href="#rule-of-thumb" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-swift" data-lang="swift"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8f5902;font-style:italic"&gt;// User tapped &amp;#34;Load&amp;#34; and is staring at a spinner → userInitiated&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#000"&gt;DispatchQueue&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;.&lt;/span&gt;&lt;span style="color:#000"&gt;global&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;(&lt;/span&gt;&lt;span style="color:#000"&gt;qos&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt; &lt;span style="color:#000;font-weight:bold"&gt;.&lt;/span&gt;&lt;span style="color:#000"&gt;userInitiated&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;).&lt;/span&gt;&lt;span style="color:#000"&gt;async&lt;/span&gt; &lt;span style="color:#000;font-weight:bold"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#204a87;font-weight:bold"&gt;let&lt;/span&gt; &lt;span style="color:#000"&gt;data&lt;/span&gt; &lt;span style="color:#000;font-weight:bold"&gt;=&lt;/span&gt; &lt;span style="color:#000"&gt;loadCriticalData&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#000;font-weight:bold"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8f5902;font-style:italic"&gt;// Background sync / download with a progress bar → utility&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#000"&gt;DispatchQueue&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;.&lt;/span&gt;&lt;span style="color:#000"&gt;global&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;(&lt;/span&gt;&lt;span style="color:#000"&gt;qos&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt; &lt;span style="color:#000;font-weight:bold"&gt;.&lt;/span&gt;&lt;span style="color:#000"&gt;utility&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;).&lt;/span&gt;&lt;span style="color:#000"&gt;async&lt;/span&gt; &lt;span style="color:#000;font-weight:bold"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#000"&gt;downloadLargeFile&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#000;font-weight:bold"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;If you use &lt;code&gt;.userInitiated&lt;/code&gt; for everything&lt;/strong&gt;, you waste battery and CPU on non-urgent work. &lt;strong&gt;If you use &lt;code&gt;.utility&lt;/code&gt; for user-blocking tasks&lt;/strong&gt;, the UI will feel sluggish because the system may deprioritize the work.&lt;/p&gt;</description></item></channel></rss>