5

In coding competitions we encounter inputs like:

2 3

4 5

So we do the following:

m, n = [int(x) for x in raw_input().split(' ')]

Is there a faster way of doing the same thing?

1
  • 3
    What do you mean by "faster"? Execution time or less code? Commented Oct 8, 2012 at 15:06

2 Answers 2

7

For all practical purposes, That's about as fast as you can get. On some machines, you may see a speedup on the order or a couple percent if you go with map instead of a list comprehension, but that's not guaranteed.

Here's some quick timings on my machine:

from itertools import imap
#map
>>> timeit.timeit('x,y = map(int,line.split(" "))','from __main__ import line')
4.7857139110565186
>>> timeit.timeit('x,y = map(int,line.split())','from __main__ import line')
4.5680718421936035
#list comprehension
>>> timeit.timeit('x,y = [int(x) for x in line.split(" ")]','from __main__ import line')
4.3816750049591064
>>> timeit.timeit('x,y = [int(x) for x in line.split()]','from __main__ import line')
4.3246541023254395
#itertools.imap
>>> timeit.timeit('x,y = imap(int,line.split(" "))','from __main__ import line,imap')
4.431504011154175
>>> timeit.timeit('x,y = imap(int,line.split())','from __main__ import line,imap')
4.3257410526275635
#generator expression
>>> timeit.timeit('x,y = (int(x) for x in line.split(" "))','from __main__ import line')
4.897794961929321
>>> timeit.timeit('x,y = (int(x) for x in line.split())','from __main__ import line')
4.732620000839233

Surprisingly, split() seems to perform better than split(" ").


If you're guaranteed to have ascii input of numbers between 0 and 9, you can do a good bit better using ord:

>>>timeit.timeit('x,y = [ord(x)-48 for x in line.split(" ")]','from __main__ import line')
1.377655029296875
>>> timeit.timeit('x,y = [ord(x)-48 for x in line.split()]','from __main__ import line')
1.3243558406829834

But that imposes a severe restriction on your inputs.


One other idea that you could try (I have no idea what the performance implications would be), but you could read your lines from sys.stdin:

import sys
for line in sys.stdin:
    x,y = [ord(x)-48 for x in line.split()]
Sign up to request clarification or add additional context in comments.

3 Comments

split() and split(" ") don't actually do the same thing... docs.python.org/library/stdtypes.html#str.split
@JonClements -- I understand that they're not the same. split() and split(None) are the same. However, split() is more general than split(" ") which is why I'm surprised that it is faster (it needs to do test for "\t" instead of just ' ', or runs of ' ' instead of single ' ' for example)
I'm guessing then that split() is probably using something like strtok(str, " \t") in C which deals with consecutive delimiters... While, split(' ') has to go against that behaviour (and also potentially build a larger result list with ''s)
1

Use map(), it's faster than list comprehensions when used with built-in functions:

m, n = map(int, raw_input().split())

3 Comments

Yes, I'm aware of this. I've done the timings myself many times (and gotten conflicting results). All I'm saying is that the results can vary from machine to machine and that this sort of micro-optimization is unlikely to make any real difference.
on using map in my submission,execution time reduced from 3.86 to 3.64 seconds

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.