# 37.1 Radix vs. Comparison Sorting

## Intuitive Analysis

### Merge Sort Runtime

Merge Sort requires Θ(N log N) compares.

A key concept here is that Merge Sort’s runtime on strings of length W is Θ(N log N) if each comparison takes constant time or Θ(WN log N) if each comparison takes Θ(W) time.

Example of Θ(N log N): Strings are all different in top character.

Example of Θ(WN log N): Strings are all equal.

### LSD vs. Merge Sort

The facts:

Treating alphabet size as constant, LSD Sort has runtime Θ(WN). Merge Sort has runtime between Θ(N log N) and Θ(WN log N).

Which is better? It depends.

#### When might LSD sort be faster?

* When W is sufficiently smaller than N (or equivalently, N is really really big, or as you get to larger and larger numbers of strings, we expect LSD to pull ahead).
* Worst case strings for mergesort, the more similar they are, the more we expect LSD sort to do better.
* Sufficiently large N.
* If strings are very similar to each other.
  * Each Merge Sort comparison costs Θ(W) time.

<figure><img src="https://3031105543-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2aYwKpK43ima4gxrLWSB%2Fuploads%2Fgit-blob-ee5286dc6963e044b56f690b87817127e714d0cd%2Fimage%20(74).png?alt=media" alt=""><figcaption></figcaption></figure>

#### When might Merge Sort be faster?

* Strings are different, especially at the beginning.
* If strings are highly dissimilar from each other
  * Each merge sort comparison is very fast

<figure><img src="https://3031105543-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2aYwKpK43ima4gxrLWSB%2Fuploads%2Fgit-blob-c59b02b99075a12a9ab470dfd8ec5aecb14db0a3%2Fimage%20(137).png?alt=media" alt=""><figcaption></figcaption></figure>

## Cost Model Analysis

### Alternate Approach: Picking a Cost Model

An alternate approach is to pick a cost model.

* We’ll use number of characters examined.
* By “examined”, we mean:
  * Radix Sort: Calling charAt in order to count occurrences of each character.
  * Merge Sort: Calling charAt in order to compare two Strings.

### MSD vs. Mergesort

Suppose we have 100 strings of 1000 characters each.

For MSD Radix Sort, in the worst case (all strings equal), every character is examined exactly once. Thus, we have exactly 100,000 total character examinations.

<figure><img src="https://3031105543-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2aYwKpK43ima4gxrLWSB%2Fuploads%2Fgit-blob-f4bd8602943548de9fae66f3b058e9a5f9e2fdd8%2Fimage%20(144).png?alt=media" alt=""><figcaption></figcaption></figure>

For Merge Sort, estimate the total number of characters examined if all strings are equal.

Merging 100 items, assuming equal items results in always picking left:

* Comparing A\[0] to A\[50]: 2000 character examinations.
* Comparing A\[1] to A\[50]: 2000 character examinations.
* … Comparing A\[49] to A\[50]: 2000 character examinations.
* Total characters examined: 50 \* 2000 = 100000.
* Merging N strings of 1000 characters requires N/2 \* 2000 = 1000N examinations.

<figure><img src="https://3031105543-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2aYwKpK43ima4gxrLWSB%2Fuploads%2Fgit-blob-fdcbbdfbb528ddba2b4bd3be90e2f8f18e03f912%2Fscreenshot%202023-04-19%20at%2012.46.58%20AM.png?alt=media" alt=""><figcaption></figcaption></figure>

In total, we must examine approximately 1000N log2 N total characters.

* 100000 + 50000\*2 + 25000 \* 4 + … = \~660,000 characters.

<figure><img src="https://3031105543-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2aYwKpK43ima4gxrLWSB%2Fuploads%2Fgit-blob-07bf0a57580724177c697505d8c18a03c1528248%2Fimage%20(156).png?alt=media" alt=""><figcaption></figcaption></figure>

### MSD vs. Mergesort Character Examinations

For N equal strings of length 1000, we found that:

* MSD radix sort will examine \~1000N characters (For N= 100: 100,000).
* Merge sort will examine \~1000Nlog2(N) characters (For N=100: 660,000).\\

  If character examination are an appropriate cost model, we’d expect Merge Sort to be slower by a factor of log2N.\\

  To see if we’re right, we’ll need to do a computational experiment.

## Empirical Study: Radix Sort vs. Comparison Sorting

### Computational Experiment Results (Your Answers)

Computational experiment for W = 100.

* [MSD](https://algs4.cs.princeton.edu/51radix/MSD.java.html) and [merge sort](https://algs4.cs.princeton.edu/22mergesort/MergeX.java.html) implementations are highly optimized versions taken from our optional algorithms textbook.
* Does our data match our runtime hypothesis? No! Why not?
  * Maybe when MSD makes partitions, the divide and conquer cost is not accounted for.
  * Is mergesort optimized to do the timesort optimization? Unclear.
  * Maybe this is caching performance, Josh mentioned MSD has bad cache performance.
  * Maybe string comparison is not linear time somehow (keep in mind every string compare does the SAME thing. Repeated work on real machines these days tends to get optimized away).
  * Our cost model isn’t representative of everything that is happening.
  * One particularly thorny issue: **The “Just In Time” Compiler.**

<figure><img src="https://3031105543-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2aYwKpK43ima4gxrLWSB%2Fuploads%2Fgit-blob-303f89c6cad80ed7004ea7513651760fbc755a86%2Fimage%20(77).png?alt=media" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3031105543-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2aYwKpK43ima4gxrLWSB%2Fuploads%2Fgit-blob-4aafd24b62e73e1967cc07d8b03379a0556d96aa%2Fscreenshot%202023-04-19%20at%201.01.54%20AM.png?alt=media" alt=""><figcaption></figcaption></figure>
