A Merge Sort implementation for efficiency
Some comments:

Include a convenience function that takes only a list, i.e., where you don't need to provide the bounds.
Don't fight Python's inclusive-start exclusive-stop paradigm and naming.
Write docstrings to explain what the parameters mean, especially if you use unusual stuff.
Don't compute mid when you don't have to anyway.
Compute mid with integer division and from the sum (Python's ints don't overflow).
Don't reimplement slicing.
You can easily do it with copying out just the left part.
For benchmarking, I'd suggest to randomly shuffle the list instead of using a reverse-sorted list. I suspect you did the latter because you thought it's a worst case, but for example for Python's built-in sorting algorithm Timsort, it's a &quot;best case&quot;, taking only linear time. And other algorithms might also be unrealistically affected (either faster or slower than for the typical case).
Don't write an unstable merge sort, that's a sin :-P
4444444444444444444444 is unsafe. What if the list has items larger than that?

Here's my version of it, it's about three times as fast as yours both on reverse-sorted and on shuffled lists (tested with 100,000 items).
def merge(items, start, mid, stop):
    &quot;&quot;&quot;Merge sorted items[start:mid] and items[mid:stop] into items[start:stop].&quot;&quot;&quot;
    for left in items[start:mid]:
        while mid &lt; stop and items[mid] &lt; left:
            items[start] = items[mid]
            start += 1
            mid += 1
        items[start] = left
        start += 1

def mergesort_slice(items, start, stop):
    &quot;&quot;&quot;Sort items[start:stop].&quot;&quot;&quot;
    if stop - start &gt; 1:
        mid = (start + stop) // 2
        mergesort_slice(items, start, mid)
        mergesort_slice(items, mid, stop)
        merge(items, start, mid, stop)

def mergesort(items):
    mergesort_slice(items, 0, len(items))