C#9.0의 범위 모드의 switch가 비교적 똑똑하게 컴파일되었다
범위 모드의 switch식 사용하기
C#9.0에서는 switch에서 비교 연산을 지정할 수 있습니다.
원시 코드
public class C
{
public int Expr(int num) => num switch
{
<=0 => -1,
< 10 => 0,
< 20 => 1,
< 30 => 2,
< 40 => 3,
< 50 => 4,
< 60 => 5,
_ => -1,
};
}
위 코드의 컴파일 결과(IL을 C#로 컴파일)는 다음과 같습니다.컴파일 결과
public class C
{
public int Expr(int num)
{
if (num < 30)
{
if (num < 10)
{
if (num <= 0)
{
return -1;
}
return 0;
}
if (num < 20)
{
return 1;
}
return 2;
}
if (num < 50)
{
if (num < 40)
{
return 3;
}
return 4;
}
if (num < 60)
{
return 5;
}
return -1;
}
}
2분이나 검색했어.만약 이렇다면if문을 열거해도 큰 차이가 없지만 2분 동안 검색하면if문이 실행되는 횟수는log입니다2회 정도.단점 없는 고속화를 기대할 수 있기 때문에 범위를 열거한 부분에 적극적으로 switch식으로 쓰는 것이 좋다.
그나저나 switch 문장에서도 점프표를 만들 수 없는 상황에서 2점 검색으로 전환할 수 있을 것 같다.
추기
'나쁜 점은 없다'고 썼지만'대부분의 경우
0 <= num && num < 10
'는 일치하는 빈도가 매우 높으면 일치하는 빈도가 높은 순서에 따라 나열if문이 2분 탐색보다 빠른 것 같다.or 사용 시
or
도 사용해 보았어요.원시 코드
public class C
{
public int Expr(int num) => num switch
{
<=0 => -1,
< 10 or > 600 => 0,
< 20 or > 500 => 1,
< 30 or > 400 => 2,
< 40 or > 300 => 3,
< 50 or > 200 => 4,
< 60 or > 100 => 5,
_ => -1,
};
}
컴파일 결과는 다음과 같다.컴파일 결과
public class C
{
public int Expr(int num)
{
if (num > 100)
{
if (num > 300)
{
if (num > 500)
{
if (num > 600)
{
goto IL_0061;
}
goto IL_0065;
}
if (num > 400)
{
goto IL_0069;
}
goto IL_006d;
}
if (num > 200)
{
goto IL_0071;
}
}
else
{
if (num < 30)
{
if (num < 10)
{
if (num > 0)
{
goto IL_0061;
}
return -1;
}
if (num < 20)
{
goto IL_0065;
}
goto IL_0069;
}
if (num < 50)
{
if (num < 40)
{
goto IL_006d;
}
goto IL_0071;
}
if (num >= 60)
{
return -1;
}
}
return 5;
IL_0065:
return 1;
IL_0061:
return 0;
IL_0071:
return 4;
IL_0069:
return 2;
IL_006d:
return 3;
}
}
goto
약간 스파게티 같은데, 이것도 2점 탐색이다.결론
열거 범위 검사 시
switch
식이 더욱 효율적입니다!
Reference
이 문제에 관하여(C#9.0의 범위 모드의 switch가 비교적 똑똑하게 컴파일되었다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/naminodarie/articles/86c578d3765fc5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)