<?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: Isaiah Tucker</title>
    <description>The latest articles on DEV Community by Isaiah Tucker (@dragonbreathit_).</description>
    <link>https://dev.to/dragonbreathit_</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%2F3854555%2Fc0538a58-5510-4fac-8282-8a12b843a3c6.png</url>
      <title>DEV Community: Isaiah Tucker</title>
      <link>https://dev.to/dragonbreathit_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dragonbreathit_"/>
    <language>en</language>
    <item>
      <title>QuillSort — A data sorter</title>
      <dc:creator>Isaiah Tucker</dc:creator>
      <pubDate>Wed, 01 Apr 2026 03:29:53 +0000</pubDate>
      <link>https://dev.to/dragonbreathit_/quillsort-a-data-sorter-3dnf</link>
      <guid>https://dev.to/dragonbreathit_/quillsort-a-data-sorter-3dnf</guid>
      <description>&lt;p&gt;Most of the time, Python’s built-in &lt;code&gt;sorted()&lt;/code&gt; and &lt;code&gt;list.sort()&lt;/code&gt; are all you need.&lt;/p&gt;

&lt;p&gt;But if you ever try to sort &lt;em&gt;a lot&lt;/em&gt; of data—millions to billions of values, big numeric logs, or giant SQL exports—you quickly run into a wall: RAM, speed, or both.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;&lt;a href="https://pypi.org/project/quill-sort/" rel="noopener noreferrer"&gt;Quill-Sort&lt;/a&gt;&lt;/strong&gt; (&lt;code&gt;quill-sort&lt;/code&gt; on PyPI).&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/dragonbreathIT" rel="noopener noreferrer"&gt;
        dragonbreathIT
      &lt;/a&gt; / &lt;a href="https://github.com/dragonbreathIT/quill-sort" rel="noopener noreferrer"&gt;
        quill-sort
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;quill-sort&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Adaptive Ultra-Sort&lt;/strong&gt; — the fastest general-purpose sorting library for Python.&lt;/p&gt;
&lt;div class="highlight highlight-source-python notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s1"&gt;quill&lt;/span&gt; &lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-s1"&gt;quill_sort&lt;/span&gt;, &lt;span class="pl-s1"&gt;quill_sorted&lt;/span&gt;
&lt;span class="pl-en"&gt;quill_sort&lt;/span&gt;([&lt;span class="pl-c1"&gt;3&lt;/span&gt;, &lt;span class="pl-c1"&gt;1&lt;/span&gt;, &lt;span class="pl-c1"&gt;4&lt;/span&gt;, &lt;span class="pl-c1"&gt;1&lt;/span&gt;, &lt;span class="pl-c1"&gt;5&lt;/span&gt;, &lt;span class="pl-c1"&gt;9&lt;/span&gt;])               &lt;span class="pl-c"&gt;# → [1, 1, 3, 4, 5, 9]&lt;/span&gt;
&lt;span class="pl-en"&gt;quill_sort&lt;/span&gt;(&lt;span class="pl-s1"&gt;records&lt;/span&gt;, &lt;span class="pl-s1"&gt;key&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-k"&gt;lambda&lt;/span&gt; &lt;span class="pl-s1"&gt;r&lt;/span&gt;: &lt;span class="pl-s1"&gt;r&lt;/span&gt;[&lt;span class="pl-s"&gt;'age'&lt;/span&gt;])   &lt;span class="pl-c"&gt;# sort objects&lt;/span&gt;
&lt;span class="pl-en"&gt;quill_sort&lt;/span&gt;(&lt;span class="pl-s1"&gt;big_data&lt;/span&gt;, &lt;span class="pl-s1"&gt;parallel&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;True&lt;/span&gt;)           &lt;span class="pl-c"&gt;# use all CPU cores&lt;/span&gt;
&lt;span class="pl-s1"&gt;result&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-en"&gt;quill_sorted&lt;/span&gt;(&lt;span class="pl-s1"&gt;iterable&lt;/span&gt;, &lt;span class="pl-s1"&gt;reverse&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;True&lt;/span&gt;) &lt;span class="pl-c"&gt;# mirrors built-in sorted()&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;pip install quill-sort              &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; core (no dependencies)&lt;/span&gt;
pip install quill-sort[fast]        &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; + numpy + psutil for max speed&lt;/span&gt;
pip install quill-sort[all]         &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; + numpy + pandas + psutil&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Quill profiles your data at intake and routes to the optimal algorithm automatically:&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Data type&lt;/th&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;th&gt;Complexity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Dense integer range&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;np.bincount&lt;/code&gt; counting sort&lt;/td&gt;
&lt;td&gt;O(n + k)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;uint8 / uint16&lt;/td&gt;
&lt;td&gt;Radix sort (&lt;code&gt;kind='stable'&lt;/code&gt;, 1-2 passes)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/dragonbreathIT/quill-sort" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Quill is a drop-in Python sorting library that behaves like &lt;code&gt;sorted()&lt;/code&gt; and &lt;code&gt;list.sort()&lt;/code&gt;, but is &lt;em&gt;specifically optimized&lt;/em&gt; for high-volume, numeric, and external (disk-backed) sorting. It’s designed to attack the weak spots of Python’s sort, not replace it for every tiny list.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Yes, I actually sorted &lt;strong&gt;1,000,000,000 int32 values (4 GB)&lt;/strong&gt; on a 28‑core machine in about &lt;strong&gt;21 seconds&lt;/strong&gt; using Quill’s external mode.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Important:&lt;/em&gt; Quill-Sort is still under &lt;strong&gt;active, major development&lt;/strong&gt;. APIs, performance characteristics, and internal behavior may change, and bugs may occur. Additionally, the github repo isn't fully set up yet. &lt;strong&gt;Please don’t throw your only copy of critical production data at it without backups yet.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Quill-Sort?
&lt;/h2&gt;

&lt;p&gt;Quill-Sort is a &lt;em&gt;hyper-optimized sorting library for Python&lt;/em&gt; with a familiar API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;quill&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;quill_sort&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quill_sorted&lt;/span&gt;

&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;quill_sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;              &lt;span class="c1"&gt;# in-place, like list.sort()
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;quill_sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# returns new list, like sorted()
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s built for two worlds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Everyday data&lt;/em&gt;: millions of integers/floats/strings in memory.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Stupidly large data&lt;/em&gt;: hundreds of millions or even &lt;em&gt;1 billion&lt;/em&gt; integers using external disk-backed sorting (&lt;code&gt;.qwrite&lt;/code&gt; files) plus parallel workers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don’t have to think about algorithms or chunk sizes—Quill routes to the right strategy internally.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key features (in plain English)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Drop-in API&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;quill_sort()&lt;/code&gt; behaves like &lt;code&gt;list.sort()&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;quill_sorted()&lt;/code&gt; behaves like &lt;code&gt;sorted()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Type-aware strategies&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Specialized integer paths (radix, counting, NumPy-backed paths).
&lt;/li&gt;
&lt;li&gt;Float paths with proper &lt;code&gt;inf&lt;/code&gt; handling.
&lt;/li&gt;
&lt;li&gt;Strings, bytes, and custom keys supported.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fully stable&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;
Equal keys preserve order, matching Python’s sort semantics.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Early-exit detection&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;
Detects already sorted / reverse-sorted / all-same data and bails out &lt;em&gt;fast&lt;/em&gt; instead of doing full work.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Parallel sorting&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;
Can fan out across cores for large workloads.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;External mode (.qwrite)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;
When data is too big for RAM, Quill can spill to disk, partition into pages, and run a multi-phase external sort with automatic temp-file management.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Plugins for NumPy and Pandas&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;
Drop in a &lt;code&gt;numpy&lt;/code&gt; array, &lt;code&gt;Series&lt;/code&gt;, or &lt;code&gt;DataFrame&lt;/code&gt; and let Quill handle it.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Benchmarks vs Python’s sort (real numbers)
&lt;/h2&gt;

&lt;p&gt;All of these were run on my own machine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.13.12
&lt;/li&gt;
&lt;li&gt;28 cores
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;quill-sort&lt;/code&gt; v4.0.4&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  In-memory benchmarks
&lt;/h3&gt;

&lt;p&gt;These are single-process, in-RAM tests where Python can reasonably compete.&lt;/p&gt;

&lt;h4&gt;
  
  
  Integers with many duplicates (0–1000, 2M elements)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Quill : 0.1203s
Python: 0.1734s
Speedup: 1.44x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quill uses integer-specific strategies here, so it wins especially hard on high-dup distributions.&lt;/p&gt;

&lt;h4&gt;
  
  
  Floats with ±inf (~1.02M elements)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Quill : 0.1069s
Python: 0.1206s
Speedup: 1.13x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even against CPython’s heavily optimized timsort, Quill still edges ahead on large float arrays.&lt;/p&gt;

&lt;h4&gt;
  
  
  Random strings (3–40 chars, 500K elements)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Quill : 0.1089s
Python: 0.0954s
Speedup: ~0.88x (Python slightly faster)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For string-heavy workloads, Python’s built-in sort is already excellent. Quill stays in the same ballpark, but its real superpowers show up on numeric and huge-scale datasets.&lt;/p&gt;




&lt;h2&gt;
  
  
  The fun part: 1,000,000,000 integers
&lt;/h2&gt;

&lt;p&gt;Here’s the one-billion 32‑bit integer stress test I ran:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Target: &lt;em&gt;1,000,000,000&lt;/em&gt; integers
&lt;/li&gt;
&lt;li&gt;Type: int32
&lt;/li&gt;
&lt;li&gt;Range: 0–999,999,999
&lt;/li&gt;
&lt;li&gt;Data size: &lt;em&gt;4.0 GB&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Machine: 28 cores, ~17 GB RAM
&lt;/li&gt;
&lt;li&gt;Quill: v4.0.4&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;High-level strategy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;28 worker processes (one per core).
&lt;/li&gt;
&lt;li&gt;Phase 1: generate + radix partition into buckets (.qwrite).
&lt;/li&gt;
&lt;li&gt;Phase 2: parallel bucket merge + sort + concatenation.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Elements sorted : 1,000,000,000
Sort errors     : 0  [OK] perfect
Total time      : 21.3s
Throughput      : 46.9M elements/second
Output file     : 4.00 GB
Temp files      : 7408 .qwrite files (cleaned automatically)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not something CPython’s built-in sort can do directly on this hardware. With normal Python lists of &lt;code&gt;int&lt;/code&gt;, you would run out of RAM long before 1B elements. Even with compact buffers, you’d still need hand-written external sorting logic (chunk → sort → write → merge) plus temp-file management.&lt;/p&gt;

&lt;p&gt;Quill wraps all of that into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;quill_sort&lt;/span&gt;&lt;span class="p"&gt;(...,&lt;/span&gt; &lt;span class="n"&gt;high_performance_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  External mode in action
&lt;/h2&gt;

&lt;p&gt;When Quill detects that a dataset is too big for the available RAM, it prompts to enable &lt;em&gt;external mode&lt;/em&gt; and shows you the plan:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many pages it will create.
&lt;/li&gt;
&lt;li&gt;Approximate sizes.
&lt;/li&gt;
&lt;li&gt;Where temp &lt;code&gt;.qwrite&lt;/code&gt; files will live.
&lt;/li&gt;
&lt;li&gt;That cleanup is automatic (even on crash).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once enabled, Quill:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Splits data into pages.
&lt;/li&gt;
&lt;li&gt;Sorts each page (in parallel).
&lt;/li&gt;
&lt;li&gt;Writes each sorted page as a &lt;code&gt;.qwrite&lt;/code&gt; file.
&lt;/li&gt;
&lt;li&gt;Runs a k-way merge over those files.
&lt;/li&gt;
&lt;li&gt;Streams the final sorted output.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;From your perspective, it’s still just:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;quill_sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;high_performance_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  When should you use Quill?
&lt;/h2&gt;

&lt;p&gt;You probably don’t need Quill if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You’re sorting small or medium lists (thousands → low millions) casually.&lt;/li&gt;
&lt;li&gt;You only care about simple string sorting and are happy with Python’s built-ins.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quill starts to earn its keep when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You’re regularly sorting &lt;em&gt;millions&lt;/em&gt; of ints/floats and care about shaving off 20–40% time.&lt;/li&gt;
&lt;li&gt;You work with &lt;em&gt;log data, telemetry, event streams, or numeric analytics&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;You hit RAM ceilings and need a &lt;em&gt;proper external sort&lt;/em&gt; that doesn’t require reinventing merge sort on disk.&lt;/li&gt;
&lt;li&gt;You want &lt;em&gt;drop-in speedups&lt;/em&gt; without rewriting everything in C++ or Rust.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember: &lt;em&gt;this project is still under major development&lt;/em&gt;. Expect sharp edges, and please report bugs if you hit them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick start
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;quill-sort[fast]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basic usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;quill&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;quill_sort&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quill_sorted&lt;/span&gt;

&lt;span class="c1"&gt;# In-place
&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;4&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="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;7&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="nf"&gt;quill_sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# New list
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;quill_sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Reverse sort
&lt;/span&gt;&lt;span class="nf"&gt;quill_sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# With key function
&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;age&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bob&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;age&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="nf"&gt;quill_sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;age&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;External “I have way too much data” mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;quill_sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="n"&gt;high_performance_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# allow external sort
&lt;/span&gt;           &lt;span class="n"&gt;silent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                &lt;span class="c1"&gt;# see progress output
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;a href="https://pypi.org/project/quill-sort/" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;Install Quill-Sort and try it yourself!&lt;/a&gt;
&lt;/p&gt;

</description>
      <category>python</category>
      <category>datascience</category>
      <category>performance</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
