0

During the interview, I was given a piece of Python code:

"".join([x for x in "\x63\x6c\x75\x62"])

The interviewer asked me: Can you make this piece of code faster with just a tiny tweak to the existing code? The output should stay exactly the same.

Enough to say, I failed this question. I'm wondering if anything could help me understand how to optimize this code?

Thanks a lot.

Michal Sz.
  • 171
  • 2
  • 8

4 Answers4

11
"".join([x for x in "\x63\x6c\x75\x62"])

is a very redundant way of doing:

"\x63\x6c\x75\x62"

In general, you should not do

x for x in "\x63\x6c\x75\x62"

this is useless because you don't transform or filter x in any way (and it's of course slower).

One last thing, if the interviewer meant to remove the [] he/she was also wrong.

"".join(x for x in "\x63\x6c\x75\x62")

is slower that with the listcomp because join has to build a list anyway (useful to remember this when creating useful comprehension, unlike that one, see Joining strings. Generator or list comprehension?)

Conclusion: let's not join the club

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • 1
    Thank you for mentioning the generator bit – TerryA Mar 09 '18 at 08:38
  • Very interesting point about the generator. Hadn't thought of that. – Kaushik NP Mar 09 '18 at 08:46
  • So what exactly is the overhead on the generator expression? ``Join`` casts the generator to a list. So we can skip the creation of the generator entirely and save time by that? – Yannic Hamann Mar 09 '18 at 09:00
  • 1
    the provided link explains it more in detail. Creating a list comprehension and providing it to `join` is faster than having `join` force iteration on the generator to create an internal list (iteration call overhead) – Jean-François Fabre Mar 09 '18 at 09:02
  • I looked at it, so I guess its both combined. You don't have to create a generator, which is useless in this case since you could directly pass the list, and therefore you don't have to do the extra cast and iterate over it. Thanks! – Yannic Hamann Mar 09 '18 at 09:11
2

Nothing to do:

>>> res = "\x63\x6c\x75\x62"
>>> res
'club'

It just a different way to enter the sting.

Mike Müller
  • 82,630
  • 20
  • 166
  • 161
0

Ok guys, what about this version?

"".join(* ["\x63\x6c\x75\x62"])
Michal Sz.
  • 171
  • 2
  • 8
-1
%%timeit
"".join([x for x in "\x63\x6c\x75\x62"])
289 ns ± 3.54 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Outputs club.

%%timeit 
"".join(["\x63\x6c\x75\x62"])  
66.8 ns ± 0.46 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Outputs club.

[x for x...] is useless here. Removing it makes the code running 4 times faster.

Tom Wojcik
  • 5,471
  • 4
  • 32
  • 44