ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 28

  1. Blog

bisect vs Linear vs set: Lookup Lab

Hands-on bisect.insort vs linear vs set lab: real ops/s for mixed sorted-list insert and membership lookup workloads, measured on Linux localhost (lab).

Aditya Challa·30 September 2026·4 min read

Summary
On this page
  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — lookup (p50)
  5. Insert build-to-N (p50)
  6. Mixed 70/30 (seed 2 000, 10 k steps)
  7. Reading it
  8. Why list+bisect still exists
  9. Pitfalls
  10. When to pick what
  11. Reproduce
  12. Closing

Intro — what this post promises

Need a sorted collection with inserts and membership checks? This lab compares bisect.insort + bisect_left, a linear sorted insert, and a set (fast, but order-free) on Linux localhost — pure lookup, pure insert, and a 70/30 lookup/insert mix.

Related links:

  • sorted vs heapq vs bisect localhost lab
  • nlargest vs sorted slice localhost lab
  • frozenset vs set membership localhost lab
  • set vs list membership localhost lab
  • itertools chain vs flatten localhost lab
  • Counter vs dict tally localhost lab
  • array vs list ints localhost lab
  • perf_counter vs time localhost lab

Lab honesty (1 Oct 2026 IST): Python 3.13.5. bisect on a list is O(log n) search but O(n) insert (element shift). Affiliates: 0. Complements the sorted/heapq/bisect overview with mixed workloads.

Verdict up front: lookup n=1 000 — set ~26M/s, bisect ~4.5M, linear ~0.24M (set ~5.8× bisect; bisect ~19× linear). Mixed s=2 000: set ~5.1× bisect; bisect ~181× linear-sorted insert.


Arms

ArmKeeps order?Pattern
bisectyesbisect_left / insort
linear sorted insertyesscan + list.insert
linear append + inno after appendsunsorted growth
setnoin / .add
sort-onceyes at endappend all then sort

Lab topology

lookup: 50k probes on sizes 100/1k/10k
insert: grow to N=1k/5k/10k
mixed: seed S, 70% lookup / 30% insert

Script: lab-evidence/68-bisect-vs-linear-lookup/results/run_lab.py.


Lead table — lookup (p50)

Armops/sns/op
set n=1 00026,145,41838.2
bisect n=1 0004,470,967223.7
linear n=1 000241,3954142.6
set n=10 00024,302,21141.1
bisect n=10 0003,504,040285.4
linear n=10 00023,75842090.4

Insert build-to-N (p50)

Armops/sns/op
append (unsorted) n=5 00088,903,11511.2
set.add n=5 00019,772,92850.6
sort once n=5 0009,282,017107.7
insort n=5 0002,673,781374.0

Batch load? sort once ~3.5× repeated insort. Online sorted inserts pay the shift.


Mixed 70/30 (seed 2 000, 10 k steps)

Armops/sns/op
set15,631,17964.0
bisect3,075,871325.1
linear append+in103,5329658.8
linear sorted insert17,02958724.9

Reading it

  • Need order + online inserts — bisect beats hand linear-sorted insert by ~181× on the mix; still loses to set on raw speed.
  • Need membership only — set / frozenset (~6× bisect at n=1 k).
  • Batch then query sorted — append + one sort, not N× insort (~3.5×).
  • insort is not free — logarithmic find + linear memmove.

Why list+bisect still exists

When you must binary-search a sequence, emit sorted output, or interop with APIs that want a list, bisect is the stdlib tool. For hot membership alone, paying O(n) shifts is the wrong tax — use a set (or a tree/skiplist if you need both order and faster inserts than a list).


Pitfalls

  1. Using bisect for membership-only maps — set wins.
  2. insorting a bulk load — sort once.
  3. Forgetting insert is O(n) — large n + many inserts → consider other structures.
  4. Assuming set preserves order — it does not (use sorted list / SortedDict recipes).

When to pick what

NeedPrefer
Membership onlyset
Sorted + rare insertslist + bisect
Sorted + bulk buildappend + sort
Sorted + heavy online insertsspecialized sorted container

Reproduce

python3 lab-evidence/68-bisect-vs-linear-lookup/results/run_lab.py

Evidence: /workspace/lab-evidence/68-bisect-vs-linear-lookup/results/.


Closing

Order costs. On this box set led bisect by ~5.8× on lookup and ~5.1× on a mixed workload, while bisect crushed linear-sorted insert by ~181×. Pick set for speed, bisect when sorted order is a product requirement.

bisectinsortbisect_leftsorted listset membershippythonlocalhost labsre

Lab evidence

What I found running this

Lab 1 Oct 2026 IST. Python 3.13.5. lookup n=1000: set 26.1M bisect 4.5M linear 0.24M (set5.8x bisect; bisect19x linear). mixed s2000: set5.1x bisect; bisect181x linear-sorted. Affiliates: 0. Evidence: lab-evidence/68-bisect-vs-linear-lookup/.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Related links

  • Plate 17

    platform vs os.uname Inventory: Localhost Lab

    Hands-on platform.platform vs os.uname host inventory lab: real ops/s plus cache notes, measured on Linux localhost today in this hands-on lab for SREs.

    1 Oct 2026

  • Plate 50

    signal vs threading.Event Wakeup: Localhost Lab

    Hands-on signal SIGUSR1 vs threading.Event wakeup lab: real p50 latency in microseconds, measured on Linux localhost today in this hands-on lab for SREs.

    1 Oct 2026

  • Plate 76

    cmath vs math.hypot Magnitudes: Localhost Lab

    Hands-on cmath vs math.hypot magnitude ops lab: real ops/s for abs, polar, and phase, measured on Linux localhost today in this hands-on lab for SREs.

    1 Oct 2026

On this page

  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — lookup (p50)
  5. Insert build-to-N (p50)
  6. Mixed 70/30 (seed 2 000, 10 k steps)
  7. Reading it
  8. Why list+bisect still exists
  9. Pitfalls
  10. When to pick what
  11. Reproduce
  12. Closing
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove