TypeCasting의 성능
사이에 측정 가능한 성능 차이가 있습니까?
((TypeA) obj).method1();
((TypeA) obj).method2();
((TypeA) obj).method3();
과
var A = (TypeA) obj;
A.method1();
A.method2();
A.method3();
자주 사용하면?
나는 종종 다음과 같은 것을 본다.
if (((TextBox)sender).Text.Contains('.') || ((TextBox)sender).Text.Contains(','))
이것이 성능 낭비인지 궁금합니다.
다른 작업이 거의없이 수십억 번 수행되면 측정 가능할 수 있습니다. CLR이 캐스트가 작동했다는 사실을 효과적으로 캐시할지 여부를 알 수 없으므로 다시 수행 할 필요가 없습니다. 지금 수행하지 않으면 이후 릴리스에서 수행 할 수 있습니다. 64 비트 JIT에서는 가능하지만 32 비트 버전에서는 불가능하거나 그 반대의 경우도 마찬가지입니다. 아이디어를 얻을 수 있습니다. 그래도 일반 코드에서 중요한 차이를 만들지 의심됩니다.
개인적으로 저는 두 번째 형식 의 가독성 이 더 좋으며 그게 훨씬 더 중요합니다.
@dkson : 두 가지 방법을 모두 테스트했습니다. 내 컴퓨터에서 찾은 내용은 다음과 같습니다.
성능면 에서 거의 동일 합니다. 사실, 두 번째 방법은 약간 느립니다. 그 이유는 (내 생각에) 추가 변수와 초기 캐스트 비용 때문입니다. 물론 충분한 캐스트를 사용하면 성능 비용을 되 찾을 수 있습니다. 캐스트를 20 ~ 30 회 저장 한 후에야 성능면에서도 깨지는 것 같습니다.
다음은 가장 최근의 두 테스트 실행 결과입니다.
TestMuliCast\_3x: 00:00:00.5970000
TestSingleCast\_3x: 00:00:00.6020000
TestMuliCast\_30x: 00:00:06.0930000
TestSingleCast\_30x: 00:00:06.0480000
TestMuliCast\_3x: 00:00:00.6120000
TestSingleCast\_3x: 00:00:00.6250000
TestMuliCast\_30x: 00:00:06.5490000
TestSingleCast\_30x: 00:00:06.4440000
또한 사이의 차이를 테스트 castclass
하고 isinst
. 내가 읽은 내용을 바탕으로 :
http://m3mia.blogspot.com/2007/11/comparing-isinst-to-castclass.html
http://www.codeproject.com/KB/cs/csharpcasts.aspx
http://discuss.joelonsoftware.com/ default.asp? dotnet.12.635066.13
예외가 없더라도 isinst가 castclass보다 빠를 것이라고 생각했습니다. 그러나 내 자신의 벤치 마크를 만든 후 isinst 가 castclass보다 약간 느리다는 것을 알았습니다. 매우 흥미로운. 내 결과는 다음과 같습니다.
TestEmptyLoop: 00:00:00.0870000
TestDCast\_castclass: 00:00:00.2640000
TestDCast\_isinst: 00:00:00.3780000
TestEmptyLoop: 00:00:00.0870000
TestDCast\_castclass: 00:00:00.2600000
TestDCast\_isinst: 00:00:00.3750000
그래서, Skeet 씨, 저는 정정되었습니다.
환경:
Windows Vista
최대 코어 속도 3.2Ghz
.NET Framework v2.0.50727
다음은 내가 만들고 실행 한 벤치 마크의 전체 소스입니다. ( 여기에서 사용할 수있는 Jon Skeets Microbenchmarking 프레임 워크를 사용 합니다. )
using System;
using System.Collections;
public class CastingBenchmark
{
static Int64 Iterations=100000000;
static Int64 TestWork = 0;
public static void Init(string[] args)
{
if (args.Length>0)
Iterations = Int64.Parse(args[0]);
}
public static void Reset()
{
TestWork = 0;
}
internal class BaseType { public void TestBaseMethod() { TestWork++; } }
internal class DerivedType : BaseType {
public void TestDerivedMethod() { TestWork++; }
public void TestDerivedMethod2() { TestWork++; }
public void TestDerivedMethod3() { TestWork++; }
}
[Benchmark]
public static void TestMuliCast_3x()
{
BaseType TestBaseType = new DerivedType();
for (int x = 0; x < Iterations; x++)
{
((DerivedType)TestBaseType).TestDerivedMethod();
((DerivedType)TestBaseType).TestDerivedMethod2();
((DerivedType)TestBaseType).TestDerivedMethod3();
}
}
[Benchmark]
public static void TestSingleCast_3x()
{
BaseType TestBaseType = new DerivedType();
for (int x = 0; x < Iterations; x++)
{
DerivedType TestDerivedType = (DerivedType)TestBaseType;
TestDerivedType.TestDerivedMethod();
TestDerivedType.TestDerivedMethod2();
TestDerivedType.TestDerivedMethod3();
}
}
[Benchmark]
public static void TestMuliCast_30x()
{
BaseType TestBaseType = new DerivedType();
for (int x = 0; x < Iterations; x++)
{
//Simulate 3 x 10 method calls while casting
for (int y = 0; y < 10; y++) {
((DerivedType)TestBaseType).TestDerivedMethod();
((DerivedType)TestBaseType).TestDerivedMethod2();
((DerivedType)TestBaseType).TestDerivedMethod3();
}
}
}
[Benchmark]
public static void TestSingleCast_30x()
{
BaseType TestBaseType = new DerivedType();
for (int x = 0; x < Iterations; x++)
{
DerivedType TestDerivedType = (DerivedType)TestBaseType;
//Simulate 3 x 10 method calls on already-cast object
for (int y = 0; y < 10; y++)
{
TestDerivedType.TestDerivedMethod();
TestDerivedType.TestDerivedMethod2();
TestDerivedType.TestDerivedMethod3();
}
}
}
[Benchmark]
public static void TestEmptyLoop()
{
for (int x = 0; x < Iterations; x++)
{
}
}
[Benchmark]
public static void TestDCast_castclass()
{
BaseType TestDerivedType = new DerivedType();
for (int x = 0; x < Iterations; x++)
{
((DerivedType)TestDerivedType).TestDerivedMethod();
}
}
[Benchmark]
public static void TestDCast_isinst()
{
BaseType TestDerivedType = new DerivedType();
for (int x = 0; x < Iterations; x++)
{
(TestDerivedType as DerivedType).TestDerivedMethod();
}
}
}
isinst
및 castclass
방법에 대한 결과 IL :
method public hidebysig static void TestDCast_isinst() cil managed
{
.custom instance void BenchmarkAttribute::.ctor()
.maxstack 2
.locals init (
[0] class CastingBenchmark/BaseType TestDerivedType,
[1] int32 x)
L_0000: newobj instance void CastingBenchmark/DerivedType::.ctor()
L_0005: stloc.0
L_0006: ldc.i4.0
L_0007: stloc.1
L_0008: br.s L_0019
L_000a: ldloc.0
L_000b: isinst CastingBenchmark/DerivedType
L_0010: callvirt instance void CastingBenchmark/DerivedType::TestDerivedMethod()
L_0015: ldloc.1
L_0016: ldc.i4.1
L_0017: add
L_0018: stloc.1
L_0019: ldloc.1
L_001a: conv.i8
L_001b: ldsfld int64 CastingBenchmark::Iterations
L_0020: blt.s L_000a
L_0022: ret
}
.method public hidebysig static void TestDCast_castclass() cil managed
{
.custom instance void BenchmarkAttribute::.ctor()
.maxstack 2
.locals init (
[0] class CastingBenchmark/BaseType TestDerivedType,
[1] int32 x)
L_0000: newobj instance void CastingBenchmark/DerivedType::.ctor()
L_0005: stloc.0
L_0006: ldc.i4.0
L_0007: stloc.1
L_0008: br.s L_0019
L_000a: ldloc.0
L_000b: castclass CastingBenchmark/DerivedType
L_0010: callvirt instance void CastingBenchmark/DerivedType::TestDerivedMethod()
L_0015: ldloc.1
L_0016: ldc.i4.1
L_0017: add
L_0018: stloc.1
L_0019: ldloc.1
L_001a: conv.i8
L_001b: ldsfld int64 CastingBenchmark::Iterations
L_0020: blt.s L_000a
L_0022: ret
}
참고 URL : https://stackoverflow.com/questions/1165602/performance-of-typecasting
'IT TIP' 카테고리의 다른 글
`[super viewDidLoad]`규칙 (0) | 2020.12.04 |
---|---|
SQL 주석 헤더 예 (0) | 2020.12.04 |
좋아하는 SQLPLUS 팁과 요령 (0) | 2020.12.04 |
C ++에서 클래스를 다른 클래스에서 상속하는 것으로 앞으로 선언 할 수 있습니까? (0) | 2020.12.04 |
Java의 열거 형에 함수를 추가 할 수 있습니까? (0) | 2020.12.04 |