<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Tommaso Coviello — notes</title><description>Projects and notes on what I build and learn.</description><link>https://kovdev.me/</link><language>en</language><item><title>The Work That Disappears</title><link>https://kovdev.me/notes/the-work-that-disappears/</link><guid isPermaLink="true">https://kovdev.me/notes/the-work-that-disappears/</guid><description>The beauty of mathematical optimization: finding better answers, removing unnecessary work, and knowing what a program must preserve.</description><pubDate>Mon, 14 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;the-work-that-disappears&quot;&gt;The Work That Disappears&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;On mathematical optimization, programming, and the pleasure of understanding what is necessary.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I find it difficult to leave a repeated calculation alone. Once I have noticed that its answer is already available somewhere, each new execution feels like an unanswered question about the program.&lt;/p&gt;
&lt;p&gt;That feeling is useful, but it is not a performance model. I can spend an hour removing work that costs almost nothing. I can also make code shorter while making it harder to understand. Learning to optimize has meant learning to distinguish the things I want to revisit from the things the machine, or its user, actually needs improved.&lt;/p&gt;
&lt;p&gt;The changes I enjoy most satisfy both kinds of attention. A better formulation gives the computer less to do and gives me less uncertainty to carry. I can explain why a family of possibilities need not be explored, or why an intermediate result need not exist.&lt;/p&gt;
&lt;p&gt;This is where mathematical optimization becomes beautiful to me: a reason is found, and some work is no longer necessary.&lt;/p&gt;
&lt;h2 id=&quot;what-a-better-answer-owes-us&quot;&gt;What a better answer owes us&lt;/h2&gt;
&lt;p&gt;An optimization problem needs a set of choices, an objective by which to compare them, and constraints that determine which choices are allowed. Without those ingredients, &lt;em&gt;better&lt;/em&gt; remains a preference rather than a mathematical claim. &lt;a href=&quot;#source-1&quot;&gt;[1]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Writing them down is already an act of clarification. For a program, should we reduce its average running time, its longest acceptable delay, or its memory use? Must its output remain identical? Which inputs matter? A faster implementation that silently abandons a requirement has changed the question.&lt;/p&gt;
&lt;p&gt;Consider a small allocation problem. We have ten units to distribute between two destinations. Suppose we assign the following cost:&lt;/p&gt;
&lt;p&gt;&lt;p&gt;Minimize &lt;var&gt;x&lt;/var&gt;² + 4&lt;var&gt;y&lt;/var&gt;², subject to &lt;var&gt;x&lt;/var&gt; + &lt;var&gt;y&lt;/var&gt; = 10 and &lt;var&gt;x&lt;/var&gt;, &lt;var&gt;y&lt;/var&gt; ≥ 0.&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;The coefficient four is an assumption of this model, not a fact about allocation in general. Equal shares would cost 125. We could search for an improvement, but the constraint lets us rewrite the expression exactly:&lt;/p&gt;
&lt;p&gt;&lt;p&gt;&lt;var&gt;x&lt;/var&gt;² + 4&lt;var&gt;y&lt;/var&gt;² = 80 + (&lt;var&gt;x&lt;/var&gt; − 4&lt;var&gt;y&lt;/var&gt;)² / 5.&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;The squared term cannot be negative. Every feasible allocation therefore costs at least 80. Choosing &lt;em&gt;x&lt;/em&gt; = 8 and &lt;em&gt;y&lt;/em&gt; = 2 makes that term zero and reaches the bound.&lt;/p&gt;
&lt;p&gt;The answer is accompanied by a reason to stop. We have not merely failed to find anything better; we have shown that nothing better is permitted by the model.&lt;/p&gt;
&lt;p&gt;This distinction matters more to me than the numerical improvement. An answer without a justification leaves the search open in my head. A matching lower bound closes it without asking for trust.&lt;/p&gt;
&lt;p&gt;Convex optimization offers a wider version of this reassurance: when the objective and feasible set are convex, every local minimum is global. Duality supplies another powerful idea: a valid lower bound can certify a feasible solution’s optimality when their values agree. Neither statement promises that every optimization problem is easy. Each identifies structure that makes a particular conclusion defensible. &lt;a href=&quot;#source-1&quot;&gt;[1]&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;what-the-future-needs-to-remember&quot;&gt;What the future needs to remember&lt;/h2&gt;
&lt;p&gt;Finding an optimal answer and optimizing a program are different tasks. The first concerns which answer to choose; the second concerns the resources required to obtain an acceptable answer. A scheduling problem lets us watch them meet.&lt;/p&gt;
&lt;p&gt;Suppose each job has a fixed start, a fixed end, and an integer value. Only one job may run at a time. We want a compatible selection with maximum total value. A job ending at time five may be followed by one starting at time five: the intervals include their start but exclude their end.&lt;/p&gt;
&lt;p&gt;Choosing the most valuable individual job is unreliable. A job occupying times zero through five and worth ten loses to two compatible jobs worth five and six. Listing every subset would settle the question, but &lt;em&gt;n&lt;/em&gt; jobs have 2ⁿ subsets. We need a better account of what makes one choice relevant to another.&lt;/p&gt;
&lt;p&gt;Sort the jobs by finishing time and number them from one. Let &lt;code&gt;best[j]&lt;/code&gt; mean the largest total value available among the first &lt;code&gt;j&lt;/code&gt; jobs. Let &lt;code&gt;p(j)&lt;/code&gt; be the number of earlier jobs ending no later than job &lt;code&gt;j&lt;/code&gt; begins. Those jobs form a prefix of the sorted list.&lt;/p&gt;
&lt;p&gt;Any optimum either excludes job &lt;code&gt;j&lt;/code&gt;, leaving &lt;code&gt;best[j - 1]&lt;/code&gt;, or includes it, leaving only that compatible prefix. Hence:&lt;/p&gt;
&lt;figure class=&quot;code&quot;&gt;&lt;div class=&quot;code-body&quot;&gt;&lt;pre class=&quot;astro-code plate&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;best[0] = 0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;best[j] = max(best[j - 1], value[j] + best[p(j)])&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;This is the standard weighted interval scheduling recurrence. Its justification is exhaustive without being an exhaustive search: the two cases cover every solution, and each refers to a smaller problem of the same form. &lt;a href=&quot;#source-2&quot;&gt;[2]&lt;/a&gt; &lt;a href=&quot;#source-3&quot;&gt;[3]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here is a Python implementation that returns both the value and a schedule achieving it. Time is measured in integer ticks; values are integers too. Negative values are allowed, and selecting nothing is valid.&lt;/p&gt;
&lt;figure class=&quot;code&quot;&gt;&lt;div class=&quot;code-body&quot;&gt;&lt;pre class=&quot;astro-code plate&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;from bisect import bisect_right&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;from collections.abc import Iterable&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;from dataclasses import dataclass&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;@dataclass(frozen=True)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;class Job:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;    start: int&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;    end: int&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;    value: int&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;    def __post_init__(self) -&amp;gt; None:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;        if any(type(x) is not int for x in (self.start, self.end, self.value)):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;            raise TypeError(&lt;/span&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;&amp;quot;Job fields must be integers.&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;        if self.start &amp;gt;= self.end:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;            raise ValueError(&lt;/span&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;&amp;quot;A job must end after it starts.&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;def optimal_schedule(jobs: Iterable[Job]) -&amp;gt; tuple[int, list[Job]]:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;    ordered = sorted(jobs, key=lambda job: job.end)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;    ends = [job.end for job in ordered]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;    previous: list[int] = []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;    best = [0]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;    for i, job in enumerate(ordered):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;        # This prefix length is also an index into best.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;        prefix = bisect_right(ends, job.start, 0, i)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;        previous.append(prefix)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;        best.append(max(best[-1], job.value + best[prefix]))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;    chosen: list[Job] = []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;    i = len(ordered)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;    while i:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;        if best[i] == best[i - 1]:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;            i -= 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;        else:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;            chosen.append(ordered[i - 1])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;            i = previous[i - 1]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;    chosen.reverse()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;    return best[-1], chosen&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;jobs = [Job(0, 3, 5), Job(3, 5, 6), Job(0, 5, 10), Job(5, 6, 2)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;score, schedule = optimal_schedule(jobs)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;assert score == 13&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;assert schedule == [jobs[0], jobs[1], jobs[3]]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;Sorting and binary searches take O(&lt;em&gt;n&lt;/em&gt; log &lt;em&gt;n&lt;/em&gt;) time; the recurrence and reconstruction take O(&lt;em&gt;n&lt;/em&gt;). Storage is O(&lt;em&gt;n&lt;/em&gt;), under the usual model that treats integer comparisons and arithmetic as constant-cost operations. Python’s &lt;code&gt;bisect_right&lt;/code&gt; gives the boundary we need, including jobs whose end equals the next start. &lt;a href=&quot;#source-2&quot;&gt;[2]&lt;/a&gt; &lt;a href=&quot;#source-4&quot;&gt;[4]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The important compression is conceptual. For each compatible prefix, the recurrence needs its best achievable value, not every history that could produce it. Histories still matter when reconstructing an actual schedule, but they do not all need to survive as separate candidates. &lt;a href=&quot;#source-3&quot;&gt;[3]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That is the detail I return to: forgetting is safe only after we have identified what the future can depend on. Add a rule that consecutive jobs require setup time depending on their identities, and the prefix value alone no longer tells us enough. The state would need to change.&lt;/p&gt;
&lt;h2 id=&quot;an-order-worth-keeping&quot;&gt;An order worth keeping&lt;/h2&gt;
&lt;p&gt;The same pleasure appears in less conspicuously mathematical code. Consider this SQLite schema and query:&lt;/p&gt;
&lt;figure class=&quot;code&quot;&gt;&lt;div class=&quot;code-body&quot;&gt;&lt;pre class=&quot;astro-code plate&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;CREATE TABLE events (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;    id INTEGER PRIMARY KEY,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;    owner_id INTEGER NOT NULL,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;    starts_at INTEGER NOT NULL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;CREATE INDEX events_by_owner_and_start&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;    ON events(owner_id, starts_at);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;EXPLAIN QUERY PLAN&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;SELECT starts_at&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;FROM events&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;WHERE owner_id = 7&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;ORDER BY starts_at;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;The index places entries in owner order, then start-time order. SQLite can use it to locate one owner’s entries, return them chronologically, and obtain the requested column without consulting the table. It is a &lt;em&gt;covering index&lt;/em&gt;: the information this query needs is already present. A separate sort can disappear. &lt;a href=&quot;#source-5&quot;&gt;[5]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The SQL still asks for ordered results. The improvement comes from arranging data so that the requested order is available at the point of use.&lt;/p&gt;
&lt;p&gt;This is an exchange, not a free deletion. An additional structure must be stored and maintained. Whether the exchange is worthwhile depends on the workload. I would inspect &lt;code&gt;EXPLAIN QUERY PLAN&lt;/code&gt; rather than infer the execution strategy from the query’s appearance; SQLite documents both covering-index plans and the temporary sorting structures that an index can avoid. &lt;a href=&quot;#source-5&quot;&gt;[5]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;What satisfies me here is the fit between the question and the representation. The program does not need a cleverer answer to “how should I sort these rows?” It needs to notice when that question has already been answered.&lt;/p&gt;
&lt;h2 id=&quot;doing-more-arithmetic-to-finish-sooner&quot;&gt;Doing more arithmetic to finish sooner&lt;/h2&gt;
&lt;p&gt;It would be easy to turn this into a rule that fewer calculations always mean better software. The original FlashAttention paper provides a useful correction.&lt;/p&gt;
&lt;p&gt;A conventional dense-attention implementation stores a large matrix of interactions between sequence positions. FlashAttention works in blocks, reducing transfers between a GPU’s larger memory and its smaller, faster on-chip memory. It never materializes the full attention matrix in the larger memory. During training, it recomputes some intermediates instead of retrieving them. In the authors’ experiments, this extra arithmetic accompanied faster execution because it reduced expensive memory traffic. &lt;a href=&quot;#source-6&quot;&gt;[6]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For a fixed head dimension, the dense computation remains quadratic in sequence length. The gain does not come from pretending those interactions have vanished. It comes from changing where data lives and when it is needed. &lt;a href=&quot;#source-6&quot;&gt;[6]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Remembering helped the scheduler; recomputing helped this GPU algorithm. Neither technique is a universal prescription. The important question is which resource it saves.&lt;/p&gt;
&lt;p&gt;Optimization requires a cost model with enough resemblance to the machine to be useful. Sometimes the most important operations are the ones our equations barely mention.&lt;/p&gt;
&lt;h2 id=&quot;the-promise-inside-a-transformation&quot;&gt;The promise inside a transformation&lt;/h2&gt;
&lt;p&gt;There is another boundary between an equation and its implementation: arithmetic itself.&lt;/p&gt;
&lt;p&gt;Over real numbers, addition is associative. In ordinary binary64 floating-point arithmetic, rounding makes the grouping observable. Python’s documentation explains why floating-point operations can introduce rounding error. This small example exposes the consequence: &lt;a href=&quot;#source-7&quot;&gt;[7]&lt;/a&gt;&lt;/p&gt;
&lt;figure class=&quot;code&quot;&gt;&lt;div class=&quot;code-body&quot;&gt;&lt;pre class=&quot;astro-code plate&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;a, b, c = 1e16, -1e16, 1.0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;print((a + b) + c)  &lt;/span&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;# 1.0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;print(a + (b + c))  &lt;/span&gt;&lt;span style=&quot;color:var(--fg)&quot;&gt;# 0.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;The first expression cancels the large values before adding one. In the second, adding one to the large negative value rounds back to that value, and the final addition produces zero.&lt;/p&gt;
&lt;p&gt;A transformation justified in real arithmetic therefore needs a second justification before being applied to floating-point code. LLVM makes this distinction explicit: its &lt;code&gt;reassoc&lt;/code&gt; fast-math flag permits algebraically equivalent transformations that may substantially change floating-point results. &lt;a href=&quot;#source-8&quot;&gt;[8]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For the same reason, &lt;em&gt;exact&lt;/em&gt; attention should not be read as a promise of identical floating-point bits: equality of the mathematical operations alone does not establish that guarantee. &lt;a href=&quot;#source-6&quot;&gt;[6]&lt;/a&gt; &lt;a href=&quot;#source-7&quot;&gt;[7]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There is nothing inherently wrong with accepting a controlled numerical difference. But the tolerance must belong to the specification. It cannot be invented after a benchmark improves.&lt;/p&gt;
&lt;p&gt;Before changing an implementation, I want to know what it owes its caller. Sometimes that is identical output. Sometimes it is an error bound. Sometimes the order of otherwise equal results matters. These details are not obstacles surrounding the real optimization; they define the space in which it is allowed to happen.&lt;/p&gt;
&lt;h2 id=&quot;where-attention-belongs&quot;&gt;Where attention belongs&lt;/h2&gt;
&lt;p&gt;Even a correct improvement can be aimed at the wrong place.&lt;/p&gt;
&lt;p&gt;Amdahl’s argument about the limits of parallel execution has a simple application to any isolated speedup. Suppose a fraction &lt;em&gt;p&lt;/em&gt; of a fixed workload’s original running time belongs to the part we improve. If that part becomes &lt;em&gt;s&lt;/em&gt; times faster while everything else stays unchanged, with no added overhead, then:&lt;/p&gt;
&lt;p&gt;&lt;p&gt;overall speedup = 1 / ((1 − &lt;var&gt;p&lt;/var&gt;) + &lt;var&gt;p&lt;/var&gt; / &lt;var&gt;s&lt;/var&gt;).&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;If the part accounts for 10% of the original time, even making it instantaneous leaves the other 90%. The maximum overall speedup is 1 / 0.9, approximately 1.11. Ten times faster locally would give about 1.10 overall. These are consequences of the stated model, not benchmark results. &lt;a href=&quot;#source-9&quot;&gt;[9]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I appreciate this limit because it puts a boundary around my own attention. The code that keeps attracting me is not necessarily the code that deserves another evening.&lt;/p&gt;
&lt;p&gt;Knuth’s discussion of optimization makes room for both restraint and care: he warns against pursuing efficiencies in noncritical code while defending worthwhile improvements in the parts identified as important. Measurement is central to that distinction. &lt;a href=&quot;#source-10&quot;&gt;[10]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For a small Python experiment, &lt;code&gt;timeit&lt;/code&gt; is useful precisely when its conditions are understood. Setup runs outside the timed section, and garbage collection is disabled by default. Both choices can exclude work that matters in a real application. Repeated measurements help reveal timing interference; they do not make an unrepresentative workload representative. &lt;a href=&quot;#source-11&quot;&gt;[11]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For the scheduler above, I would vary the number of jobs and the pattern of overlaps, include sorting in an end-to-end comparison, and check the selected schedules against exhaustive search on small inputs before timing larger ones. For the indexed query, I would include the cost of maintaining the index if writes matter to the application.&lt;/p&gt;
&lt;p&gt;These choices belong in the explanation of a result. “Faster” should tell a reader what was measured, what was preserved, and which costs were counted.&lt;/p&gt;
&lt;h2 id=&quot;a-stopping-condition-for-the-programmer&quot;&gt;A stopping condition for the programmer&lt;/h2&gt;
&lt;p&gt;The desire to keep improving a program can outlast any useful improvement. I have to be careful with an activity in which another measurable gain is almost always imaginable.&lt;/p&gt;
&lt;p&gt;Multiple objectives make the word &lt;em&gt;optimal&lt;/em&gt; more modest. A Pareto-optimal choice is one for which no feasible alternative improves an objective without worsening another. There may be many such choices; the definition alone does not select the trade-off we should prefer. &lt;a href=&quot;#source-1&quot;&gt;[1]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That leaves room for judgment. I might accept a little more memory to make a latency requirement dependable. I might keep a slower implementation because the faster one would be difficult to verify and the difference is irrelevant to its use. Those decisions need reasons, but they need not apologize for declining the smallest number on a chart.&lt;/p&gt;
&lt;p&gt;I also want room to study an optimization simply because it interests me. An evening spent understanding why a recurrence works can be worthwhile even when no application needs the result. Curiosity and engineering have different stopping conditions. Confusing them makes a learning exercise look like a delivery failure, or makes a private fascination look like a product requirement.&lt;/p&gt;
&lt;p&gt;The beauty I am looking for survives that distinction. It is there in the allocation whose lower bound meets its cost, in the scheduling state that remembers exactly enough, and in the data arrangement that makes a later operation unnecessary.&lt;/p&gt;
&lt;p&gt;After a good optimization, I want to be able to explain both the answer and the absence of the work we removed. The program still owes its caller the same promise. We have understood enough to keep it with less.&lt;/p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;/h2&gt;
&lt;p id=&quot;source-1&quot;&gt;&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt; Stephen Boyd and Lieven Vandenberghe, &lt;em&gt;Convex Optimization&lt;/em&gt;, Cambridge University Press, 2004. Sections 4.1, 4.2.2, 4.7.5, and 5.5.1: formulation, local and global optima, multiple objectives, and optimality certificates. &lt;a href=&quot;https://web.stanford.edu/~boyd/cvxbook/bv_cvxbook.pdf&quot;&gt;Author-hosted book&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;
&lt;p id=&quot;source-2&quot;&gt;&lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt; Kevin Wayne, &lt;em&gt;Dynamic Programming I&lt;/em&gt;, lecture slides accompanying Jon Kleinberg and Éva Tardos’s &lt;em&gt;Algorithm Design&lt;/em&gt;, Princeton University; revision dated February 10, 2021. Slides 9–18: weighted interval scheduling, recurrence, reconstruction, and complexity. &lt;a href=&quot;https://www.cs.princeton.edu/~wayne/kleinberg-tardos/pdf/06DynamicProgrammingI.pdf&quot;&gt;Lecture slides&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;
&lt;p id=&quot;source-3&quot;&gt;&lt;p&gt;&lt;strong&gt;3.&lt;/strong&gt; University of Washington, CSE 417, &lt;em&gt;Weighted Interval Scheduling&lt;/em&gt;, Autumn 2025. Sections 2–3: subproblems, memory structure, and reconstructing selected events. &lt;a href=&quot;https://courses.cs.washington.edu/courses/cse417/25au/readings/weighted_interval_scheduling.html&quot;&gt;Course notes&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;
&lt;p id=&quot;source-4&quot;&gt;&lt;p&gt;&lt;strong&gt;4.&lt;/strong&gt; Python Software Foundation, &lt;em&gt;bisect — Array bisection algorithm&lt;/em&gt;. The semantics and performance of binary search, including the right-hand insertion boundary. &lt;a href=&quot;https://docs.python.org/3/library/bisect.html&quot;&gt;Official documentation&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;
&lt;p id=&quot;source-5&quot;&gt;&lt;p&gt;&lt;strong&gt;5.&lt;/strong&gt; SQLite, &lt;em&gt;Query Planning&lt;/em&gt;, sections 1.6–1.7, 2.3, and 3.2; and &lt;em&gt;EXPLAIN QUERY PLAN&lt;/em&gt;, sections 1.1–1.2. Multi-column and covering indexes, ordered traversal, and temporary sorting structures. &lt;a href=&quot;https://sqlite.org/queryplanner.html&quot;&gt;Query planning&lt;/a&gt;; &lt;a href=&quot;https://sqlite.org/eqp.html&quot;&gt;plan inspection&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;
&lt;p id=&quot;source-6&quot;&gt;&lt;p&gt;&lt;strong&gt;6.&lt;/strong&gt; Tri Dao, Daniel Y. Fu, Stefano Ermon, Atri Rudra, and Christopher Ré, &lt;em&gt;FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness&lt;/em&gt;, NeurIPS 2022. Sections 3.1–3.2. &lt;a href=&quot;https://proceedings.neurips.cc/paper_files/paper/2022/file/67d57c32e20fd0a7a302cb81d36e40d5-Paper-Conference.pdf&quot;&gt;Published paper&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;
&lt;p id=&quot;source-7&quot;&gt;&lt;p&gt;&lt;strong&gt;7.&lt;/strong&gt; Python Software Foundation, &lt;em&gt;Floating-Point Arithmetic: Issues and Limitations&lt;/em&gt;. Binary representation and rounding error. &lt;a href=&quot;https://docs.python.org/3/tutorial/floatingpoint.html&quot;&gt;Official tutorial&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;
&lt;p id=&quot;source-8&quot;&gt;&lt;p&gt;&lt;strong&gt;8.&lt;/strong&gt; LLVM Project, &lt;em&gt;LLVM Language Reference Manual&lt;/em&gt;, “Fast-Math Flags,” particularly &lt;code&gt;reassoc&lt;/code&gt;. &lt;a href=&quot;https://llvm.org/docs/LangRef.html#fast-math-flags&quot;&gt;Official language reference&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;
&lt;p id=&quot;source-9&quot;&gt;&lt;p&gt;&lt;strong&gt;9.&lt;/strong&gt; Gene M. Amdahl, &lt;em&gt;Validity of the Single Processor Approach to Achieving Large Scale Computing Capabilities&lt;/em&gt;, AFIPS Spring Joint Computer Conference, 1967, pp. 483–485. The fixed-workload argument underlying the speedup calculation. &lt;a href=&quot;https://doi.org/10.1145/1465482.1465560&quot;&gt;Original publication&lt;/a&gt;; &lt;a href=&quot;https://people.cs.umass.edu/~emery/classes/cmpsci691st/readings/Conc/Amdahl-04785615.pdf&quot;&gt;2007 reprint hosted by the University of Massachusetts Amherst&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;
&lt;p id=&quot;source-10&quot;&gt;&lt;p&gt;&lt;strong&gt;10.&lt;/strong&gt; Donald E. Knuth, &lt;em&gt;Structured Programming with go to Statements&lt;/em&gt;, &lt;em&gt;ACM Computing Surveys&lt;/em&gt; 6(4), 1974, pp. 261–301, especially p. 268. Measurement, critical code, and the costs of misplaced optimization. &lt;a href=&quot;https://doi.org/10.1145/356635.356640&quot;&gt;ACM publication&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;
&lt;p id=&quot;source-11&quot;&gt;&lt;p&gt;&lt;strong&gt;11.&lt;/strong&gt; Python Software Foundation, &lt;em&gt;timeit — Measure execution time of small code snippets&lt;/em&gt;. Setup exclusions, garbage collection, and repeated measurements. &lt;a href=&quot;https://docs.python.org/3/library/timeit.html&quot;&gt;Official documentation&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;</content:encoded><category>optimization</category><category>programming</category><category>mathematics</category></item><item><title>Anthon</title><link>https://kovdev.me/projects/anthon/</link><guid isPermaLink="true">https://kovdev.me/projects/anthon/</guid><description>An AI assistant for sports mental coaching, from an initial client brief to a working product.</description><category>project</category></item><item><title>Drivewise</title><link>https://kovdev.me/projects/drivewise/</link><guid isPermaLink="true">https://kovdev.me/projects/drivewise/</guid><description>A vehicle purchase assistant that turns budget and usage preferences into explainable recommendations.</description><category>project</category></item><item><title>Amber</title><link>https://kovdev.me/projects/amber/</link><guid isPermaLink="true">https://kovdev.me/projects/amber/</guid><description>A local-first workspace for writing, connecting, and studying technical notes in ordinary files.</description><category>project</category></item><item><title>CP Lab</title><link>https://kovdev.me/projects/c-code-lab/</link><guid isPermaLink="true">https://kovdev.me/projects/c-code-lab/</guid><description>A browser workspace for practicing university C exercises, with an editor, local execution, and test feedback.</description><category>project</category></item><item><title>Physic Engine</title><link>https://kovdev.me/projects/physic-engine/</link><guid isPermaLink="true">https://kovdev.me/projects/physic-engine/</guid><description>Interactive physics simulations in C, with live vectors, graphs, and adjustable parameters.</description><category>project</category></item></channel></rss>