Programing

그렇지 않은 경우 파이썬 == vs if! =

lottogame 2020. 5. 23. 08:54
반응형

그렇지 않은 경우 파이썬 == vs if! =


이 두 코드 줄의 차이점은 무엇입니까?

if not x == 'val':

if x != 'val':

하나는 다른 것보다 더 효율적입니까?

사용하는 것이 더 좋을까요

if x == 'val':
    pass
else:

dis두 버전에 대해 생성 된 바이트 코드를 보는 데 사용 :

not ==

  4           0 LOAD_FAST                0 (foo)
              3 LOAD_FAST                1 (bar)
              6 COMPARE_OP               2 (==)
              9 UNARY_NOT           
             10 RETURN_VALUE   

!=

  4           0 LOAD_FAST                0 (foo)
              3 LOAD_FAST                1 (bar)
              6 COMPARE_OP               3 (!=)
              9 RETURN_VALUE   

후자는 작업 수가 적으므로 약간 더 효율적일 수 있습니다.


그것은 지적했다 commments에 (감사, @Quincunx 당신이 가지고있는 곳) if foo != barif not foo == bar작업의 수는 정확히 같은, 그것은 단지 것을의 COMPARE_OP변화와 POP_JUMP_IF_TRUE전환 POP_JUMP_IF_FALSE:

not ==:

  2           0 LOAD_FAST                0 (foo)
              3 LOAD_FAST                1 (bar)
              6 COMPARE_OP               2 (==)
              9 POP_JUMP_IF_TRUE        16

!=

  2           0 LOAD_FAST                0 (foo)
              3 LOAD_FAST                1 (bar)
              6 COMPARE_OP               3 (!=)
              9 POP_JUMP_IF_FALSE       16

이 경우 각 비교에 필요한 작업량에 차이가 없다면 성능 차이가 전혀 없을 것입니다.


그러나 두 버전 은 항상 논리적으로 동일하지는 않습니다 . 문제 의 구현 __eq__구현에 따라 달라지기 때문입니다 __ne__. 데이터 모델 문서 :

비교 연산자 사이에는 내재 된 관계가 없습니다. 진실은 x==y그것이 x!=y거짓 임을 암시하지 않습니다 .

예를 들면 다음과 같습니다.

>>> class Dummy(object):
    def __eq__(self, other):
        return True
    def __ne__(self, other):
        return True


>>> not Dummy() == Dummy()
False
>>> Dummy() != Dummy()
True

마지막으로, 아마도 가장 중요하게는 : 일반적 으로 개가 논리적으로 동일한 경우 x != y보다 더 읽기 쉽습니다not x == y .


@jonrsharpe는 무슨 일이 일어나고 있는지에 대한 훌륭한 설명을 가지고 있습니다. 나는 3 가지 옵션을 각각 10,000,000 번 실행할 때 시간의 차이를 보여 줄 것이라고 생각했습니다 (약간의 차이가 보일 정도로 충분합니다).

사용 된 코드 :

def a(x):
    if x != 'val':
        pass


def b(x):
    if not x == 'val':
        pass


def c(x):
    if x == 'val':
        pass
    else:
        pass


x = 1
for i in range(10000000):
    a(x)
    b(x)
    c(x)

그리고 cProfile 프로파일 러 결과 :

enter image description here

So we can see that there is a very minute difference of ~0.7% between if not x == 'val': and if x != 'val':. Of these, if x != 'val': is the fastest.

However, most surprisingly, we can see that

if x == 'val':
        pass
    else:

is in fact the fastest, and beats if x != 'val': by ~0.3%. This isn't very readable, but I guess if you wanted a negligible performance improvement, one could go down this route.


In the first one Python has to execute one more operations than necessary(instead of just checking not equal to it has to check if it is not true that it is equal, thus one more operation). It would be impossible to tell the difference from one execution, but if run many times, the second would be more efficient. Overall I would use the second one, but mathematically they are the same


>>> from dis import dis
>>> dis(compile('not 10 == 20', '', 'exec'))
  1           0 LOAD_CONST               0 (10)
              3 LOAD_CONST               1 (20)
              6 COMPARE_OP               2 (==)
              9 UNARY_NOT
             10 POP_TOP
             11 LOAD_CONST               2 (None)
             14 RETURN_VALUE
>>> dis(compile('10 != 20', '', 'exec'))
  1           0 LOAD_CONST               0 (10)
              3 LOAD_CONST               1 (20)
              6 COMPARE_OP               3 (!=)
              9 POP_TOP
             10 LOAD_CONST               2 (None)
             13 RETURN_VALUE

Here you can see that not x == y has one more instruction than x != y. So the performance difference will be very small in most cases unless you are doing millions of comparisons and even then this will likely not be the cause of a bottleneck.


An additional note, since the other answers answered your question mostly correctly, is that if a class only defines __eq__() and not __ne__(), then your COMPARE_OP (!=) will run __eq__() and negate it. At that time, your third option is likely to be a tiny bit more efficient, but should only be considered if you NEED the speed, since it's difficult to understand quickly.


It's about your way of reading it. not operator is dynamic, that's why you are able to apply it in

if not x == 'val':

But != could be read in a better context as an operator which does the opposite of what == does.


I want to expand on my readability comment above.

Again, I completely agree with readability overriding other (performance-insignificant) concerns.

What I would like to point out is the brain interprets "positive" faster than it does "negative". E.g., "stop" vs. "do not go" (a rather lousy example due to the difference in number of words).

So given a choice:

if a == b
    (do this)
else
    (do that)

is preferable to the functionally-equivalent:

if a != b
    (do that)
else
    (do this)

Less readability/understandability leads to more bugs. Perhaps not in initial coding, but the (not as smart as you!) maintenance changes...

참고URL : https://stackoverflow.com/questions/31026754/python-if-not-vs-if

반응형