Joseph Jude

Consult . Code . Coach

Double loops are slower in Swift than in Python & Typescript


code . swift . tsc . python

I have been solving problems in Project Euler in Typescript, Python, and Swift. As much as I like Swift, I was surprised to find that Swift is slower than Typescript and Python as an interpreted language. When compiled, it was faster, so I went ahead with solving Euler problems using Swift. That changed when I came to 4th problem.

4th Euler problem is about finding the largest palindrome made from the product of two 3-digit numbers. Have two loops from 999 to 100 and multiply these two indices. If the product is a palindrome and it is the larger than the previous palindrome, store it. When you exit the loops, the remaining number is the largest palindrome number made from the product of the two 3-digit numbers.

Solving this in Python is easy.

answer = 0
for i in xrange(999, 100, -1):
  for j in xrange(i, 100, -1):
    k = i * j
    s = str(k)
    if s == s[::-1] and k > answer:
      answer = k

print answer

This returns result in 0.33 seconds.

I translated the same logic into Typescript, with a modified loop indices.

var answer = 0
var k = 0

for (var i = 100; i < 1000; i++) {
  for (var j = i; j < 1000; j++) {
    k = i * j
    var kstr = k.toString()
    var reversed = kstr.split("").reverse().join("")
    if ((reversed == kstr) && (k > answer)) {
      answer = k
    }
  }
}

console.log(answer)

This runs in 0.85 seconds. Slower than Python, but still...

Next, I tried Swift.

I translated line by line to Swift.

var answer = 0
var k = 0
var s = ""
for i in (100...999).reverse() {
  for j in (100...i).reverse() {
    k = i * j
    s = String(k)
    if s == String(s.characters.reverse()) && k > answer {
      answer = k
    }
  }
}

print(answer)

It took 22 seconds!

I thought, it can't be true. After all, it is from Apple. I mean, it is Apple!

I changed the logic a bit. I changed the for loop indices to forward looping.

var answer = 0
var k = 0
var s = ""
for i in 100...1000 {
  for j in 100...1000 {
    k = i * j
    s = String(k)
    if s == String(s.characters.reverse()) && k > answer {
      answer = k
    }
  }
}

print(answer)

This took 42 seconds. What?

Ok, let me re-write it. May be double for loops are slower in Swift. Let me try while loop.

var answer = 0
var k = 0
var s = ""

var i = 100
var j = 100

while i < 1000 {
  while j < i {
    k = i * j
    s = String(k)
    if s == String(s.characters.reverse()) && k > answer {
      answer = k
    }
    j += 1
  }
  i += 1
  j = 100
}

print(answer)

This takes 41 seconds.

May be Swift is indeed slower than Python & Typescript.

Two points: In real world programming scenarios, there may not be a need for such double loops. I ran this on my MacBook Pro, not on a server


Like the post? Retweet it. Got comments? Reply.

Double loops are slower in Swift than in Python by @jjude https://t.co/zF2q69ypkr

— Joseph Jude (@jjude) October 15, 2016
Share this on: Twitter / /

Comments

comments powered by Disqus