Herding cats and happy.
Why is checking for App Store updates so slow?

You know how it goes: you open your iPhone, launch the App Store app, wait a few seconds, press the Updates button, then wait for ages while your phone tries to find any updated apps to download. I can’t figure out why that process is so ridiculously slow and thought I’d try reproducing the process for myself.

I wrote the little Python simulator below. It creates a database of a million iPhone apps and their version numbers. Then it builds a sample inventory of 1,000 apps installed on an iPhone (which is probably way more than the average). Finally, it repeatedly checks that inventory of installed apps to find the ones that have updates.

Assumptions:

  • Each app has a unique serial number.
  • Each app has a version number that can be represented as a single value, with higher values corresponding to newer versions.

That is, if a user has version 123 of app “42”, and the current version of app “42” is 124, then the user has an old version of the app.

Here’s my simulator:

#!/usr/bin/env python

import json
import random
import time

# Pretend there are 1,000,000 apps in the iPhone app store.
numberofapps = 1000000

# Create a test database of app serial numbers and their version
# numbers.
currentversion = {str(appid): random.randrange(1000) for appid in range(numberofapps)}

# Pretend that a user has 1,000 apps installed on their iPhone. Build
# a database of each of those apps' serial numbers and
# versions.
localversion = {str(random.randrange(numberofapps)): random.randrange(1000)
                for _ in range(100)}

# Serialize that database as a JSON object suitable for transmission
# to the remote server. This would only *have* to be done whenever an
# app is installed or updated, but will only take a few microseconds
# anyway.
localversionjson = json.dumps(localversion)

def checkversion(submittedversion):
    """Accept a serialized dict of app serial numbers and versions
    from a client application. Deserialize it, compare each app's
    version to the database of most recent versions, and return a
    serialized dict of the results."""

    clientverion = json.loads(submittedversion)
    updatedversion = {appid: currentversion[appid]
                      for appid, userversion in clientverion.items()
                      if userversion < currentversion[appid]}
    return json.dumps(updatedversion)

# Now check all of the versions of each app installed on our user's
# hypothetical iPhone a few thousand times.
print 'Looking for updated versions'
start = time.time()
for _ in range(10000):
    checkversion(localversionjson)
print 'Elapsed:', time.time() - start

Even though my program skips the step of actually transmitting the list of installed apps across the Internet, the code performs all the other “expensive” steps that a real service would have to do.

And on my MacBook Pro, it does so about 7,000 times a second.

My slow, unoptimized service would be able to handle about 600 million iPhone users checking for updates once a day each.

Presumably Apple does not run their App Store on a single MacBook, and they’ve likely spent some time and effort actually trying to make it fast. So why haven’t they managed to do it? Why does it take more than a fraction of a second to check for new app updates?

Blog comments powered by Disqus