-
[C#] is null vs == null쾌락없는 책임 (공부)/C# 짜잘이 2023. 1. 15. 18:47반응형
개요
친한 지인이 한번 질문을 했었습니다. 'is null이 == null보다 빠르다는데 이거 원리를 아냐?'. 완전 처음 듣는 이야기라 바로 검색을 해 봤는데 또 처음 보는 내용들이 올라와서 답장을 할 수 없었습니다. 그래서 이번에 한번 결과를 알아보기로 하고 조사를 해 봤습니다.
일단 is null이 빠른 게 맞다
일단 10,000,000개의 비교를 해본 결과 확실한 차이가 드러났습니다. 10배 이상의 차이가 나게 되므로 비교를 할 때 is로 해야 함이 확실해졌습니다.
언제부터? 7.0부터
일단 이 'is'를 통한 비교는 7.0부터 들어온 기능이라고 합니다. 또한 유니티에서는 대부분의 버전에서 C# 7.0 이상의 버전을 가지고 있지만 정확한 건 본인의 버전을 알아봐야 할 것 같습니다.
그럼 왜 어떤 차이가 있는가?
일단 먼저 가장 큰 차이는 is 키워드는 operator == 를 무시한다는 점입니다. 만일 어떤 클래스의 operator == 이 정의되어 무조건 return false;를 한다고 합시다. 이 경우에는 아래 코드에서 이상한 결과가 나오게 될 것입니다.
public class Some { public static bool operator ==(Some lhs, Some rhs) { return false; } //... } Some some = null; bool isTrueWithOperator = (some == null); // false; bool isTrueWithIsKeyword = (some is null); // true;
물론 이런 경우는 잘 없겠지만 이로 인해서 is 키워드는 조금 더 정확한 결괏값을 내는 걸 알 수 있습니다.
음 그럼 속도 차이가 단순히 함수를 하나 더 불러서 그런 걸까요? 이건 컴파일러가 실제로 생산하는 코드를 보면 알 수 있게 됩니다.
// is null 이 만든 코드 IL_0000: ldarg.1 IL_0001: ldnull IL_0002: ceq IL_0004: ret // == null이 만든 코드 IL_0000: ldarg.1 IL_0001: ldnull IL_0002: call bool C::op_Equality(class C, class C) IL_0007: ret
네 보이는 대로 is null의 경우 바로 ceq를 통해 비교하는 반면 ==의 경우 함수를 하나 더 불러 ceq를 수행하게 됩니다. 이로 인해서 누적 시 속도 차이가 도드라지는 것이죠.
다만 주의해야 할게 최신 Roslyn(컴파일러, 컴파일러 API 제공자)를 사용하면 동일한 코드를 생산해 낸다는 점에서 본인의 버전을 또 확인해봐야 할 것 같습니다.
추가적으로 아래 비교 링크에 들어가 보면 == 와 is 가 큰 시간 차이가 없다는 걸 알 수 있게 됩니다. 그러니 꼭 본인 환경에서 테스트를 진행해 봐야겠네요.
그럼 왜 유니티는 차이가 나는가? - (아직 작성 x : 유니티에서 is를 막 때려박아도 되는가?)
일단 유니티에서 UnityEngine.Object의 경우 operator == 에서 lhs, rhs 둘 중 하나가 null이라면 다른 하나는 '살아있는' 오브젝트인지 검사를 한다고 합니다. 이 부분은 유니티의 실제 객체는 C++로 작성이 되고 우리가 보는건 C# 이라 Destroy시 C++의 객체는 사라지고 아직 C#의 객체는 GC를 기다리고 있을 때 이런 일이 발생한다고 합니다.
이 부분은 유니티의 'fake null' 부분을 알아보시면 되는데 아래 글을 참고하시면 좋을 것 같습니다.
추가 : C# 9.0부터
만약 != null을 보고 싶으면 아래처럼 not 을 통해서 더 논리적으로 볼 수 있습니다.
if(!(some is null)) // 이것도 되지만 읽기 어렵습니다 if(some is object) // 이것도 같은 이야기기는 하지만 if(some is not null) // 이게 읽을 때 더 깔끔합니다
참고 링크
- StackOverflow의 글
- 속도 비교
반응형'쾌락없는 책임 (공부) > C# 짜잘이' 카테고리의 다른 글
[C#] C# 에서 상호 참조는 어떻게 해결이 될까? (0) 2022.08.06 [C#] C# string vs stringbuilder, stringbuilder는 어떻게 이득이 될까? (0) 2022.08.06