hmm I am doing a question on leetcode to verify if something is a symmetric tree and I have this one line of code:
if A.val == B.val and Issymmetric(A.left, B.right) and Issymmetric(A.right,B.left):
return True
basically if A's root value is the same as B's root value and A's left subtree is symmetric to B's right subtree plus A's right subtree is symmetric to B's left subtree, then I conclude A,B is symmetric
however this code runs very slow : 80ms on leetcode but if I change the order of the if statement to:
if Issymmetric(A.left, B.right) and Issymmetric(A.right,B.left) and A.val == B.val:
return True
this code with same logic, but takes only 52ms, I kind of assumed that comparing the root values should be done before I exhaustively process the entire left/right subtrees (in general this is more efficient, it can possibly save a lot of recursive calls)
TL;DR this gives me an impression that python evaluate short circuit and in reverse order, so I did a little test on my local environment:
def f1():
print 1
return True
def f2():
print 2
return True
if f1() and f2():
pass
# but the output I got is 1,2...
I am confused, if the order of a short circuit is from left to right, why is there a huge performance difference between my code?
I can upload my entire IsSymmetric() function, if it is necessary I did some further testing, I think 80ms is just a glitch on leetcode,thanks
This is an interesting question, that goes into some subtle areas.
When looking at a condition, as well as the speed of the condition, you need to look at how discriminating it is. I.e., wheether it immediately gives the "right" answer, or if you need to continue looking at other conditions.
It may be better to have a slow but discriminating condition first, depending on a number of factors.
Consider two functions:
def f1(c):
sleep(20)
return (c % 2) == 0
def f2(c):
sleep(25)
return (c % 4) == 0
f1()
is fast, but not very discriminating, while f2()
is slower, but more discriminating. Consider the two expressions f1(c) and f2(c)
verses f2(c) and f1(c)
for c in 0..3
=== ===== ====
c exp1 exp2
=== ===== ====
0 20+25 25+20
1 20+0 25+0
2 20+25 25+0
3 20+0 25+0
=== ===== ====
130 120
Note how having the slow
condition first results in a (slightly) smaller total time.