Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9509

[C#] 参照型における()キャストとis, asキーワードによる型変換の速さの違い

$
0
0

はじめに

C#で型変換に使う主な5つの方法の速さを比べました。

結論

()キャストを使う場合、例外が発生すると極端に遅くなるが、全く例外が発生しないケースでは最速でした。
is, asの型変換はどんなケースでもそれなりの速さが出るようです。

環境

Windows 10 Home, AMD Ryzen 5 3500 6-Core Processor(3.59 GHz), 16GB Memory, Visual Studio 2019, .Net Core 3.1

計測コード

classA{publicA(strings){member=s;}stringmember;}classB{publicB(strings){member=s;}stringmember;}//tryとcatchで囲って()キャストする方法staticvoidCast(object[]vs){foreach(objectoinvs){try{Av=(A)o;}catch{}}}//asキーワードで変換してからnullチェックする方法staticvoidAsIf(object[]vs){foreach(objectoinvs){Av=oasA;if(v==null){}}}//isキーワードで変換できるかをチェックし、そのまま変換する方法staticvoidIfIs(object[]vs){foreach(objectoinvs){if(oisAv){}}}//isキーワードでチェックしてから()キャストする方法staticvoidIfIsCast(object[]vs){foreach(objectoinvs){if(oisA){Av=(A)o;}}}//isキーワードでチェックしてからasキーワードで変換する方法staticvoidIfIsAs(object[]vs){foreach(objectoinvs){if(oisA){Av=oasA;}}}//5つの変換方法を試すstaticvoidTryMethods(intpercentageOfA){intseparator=(int)(percentageOfA/100f*ss.Length);object[]vs=ss.Select((s,i)=>i<separator?(object)newA(s):newB(s)).ToArray();Console.WriteLine($"{percentageOfA}%");Console.WriteLine($"Cast:\t\t{Measure(count,()=>Cast(vs))}");Console.WriteLine($"AsIf:\t\t{Measure(count,()=>AsIf(vs))}");Console.WriteLine($"IfIs:\t\t{Measure(count,()=>IfIs(vs))}");Console.WriteLine($"IfIsCast:\t{Measure(count,()=>IfIsCast(vs))}");Console.WriteLine($"IfIsAs:\t\t{Measure(count,()=>IfIsAs(vs))}");Console.WriteLine();}staticintcount=3000;staticstring[]ss=newstring[10000000];//エントリポイントpublicstaticvoidEntry(){Randomrandom=newRandom();for(inti=0;i<ss.Length;i++){intlength=random.Next(10);for(intj=0;j<length;j++){ss[i]+=(char)random.Next('A','z');}}Console.WriteLine($"count:\t{count}");Console.WriteLine($"length:\t{ss.Length}");Console.WriteLine();TryMethods(0);TryMethods(20);TryMethods(40);TryMethods(60);TryMethods(80);TryMethods(100);}//関数の処理にかかる時間を計測するpublicstaticTimeSpanMeasure(intcount,Actionaction){DateTimetime=DateTime.Now;for(inti=0;i<count;i++){action();}returnDateTime.Now-time;}

結果

型変換に失敗する参照が含まれている場合

例外処理が重すぎたため、以下の数値設定でひとまず測りました。
count = 1
length = 10000
表の左上の値は型変換に失敗する参照が含まれている割合です。
時間の単位は秒です。

0%1回目2回目3回目平均
Cast71.165517971.800912071.655577671.5406692
AsIf0.00028770.00032140.00025010.0002864
IfIs0.00023170.00014950.00016220.0001811
IfIsCast0.00014650.00014040.00023720.0001747
IfIsAs0.00013660.00013620.00014230.0001384
20%1回目2回目3回目平均
Cast56.651341356.584548057.056466856.7641187
AsIf0.00004060.00004400.00003630.0000403
IfIs0.00003440.00004240.00004060.0000391
IfIsCast0.00003630.00003990.00003580.0000373
IfIsAs0.00004070.00003510.00003530.0000370
40%1回目2回目3回目平均
Cast42.704239542.685528042.988746942.7928381
AsIf0.00003650.00003650.00003610.0000364
IfIs0.00003640.00003760.00003240.0000355
IfIsCast0.00003420.00003690.00003680.0000360
IfIsAs0.00004250.00003920.00003370.0000385
60%1回目2回目3回目平均
Cast28.629531328.497350428.760472728.6291181
AsIf0.00003400.00003400.00003430.0000341
IfIs0.00003170.00003150.00003250.0000319
IfIsCast0.00004900.00003690.00003720.0000410
IfIsAs0.00003150.00003060.00003110.0000311
80%1回目2回目3回目平均
Cast14.423574014.458249014.478829914.4535510
AsIf0.00003150.00003250.00003090.0000316
IfIs0.00002730.00003290.00003150.0000306
IfIsCast0.00003040.00003420.00003420.0000329
IfIsAs0.00003220.00003630.00003040.0000330
100%1回目2回目3回目平均
Cast0.00002440.00002410.00002640.0000250
AsIf0.00002860.00002720.00002590.0000272
IfIs0.00002630.00002620.00002610.0000262
IfIsCast0.00003030.00003580.00003000.0000320
IfIsAs0.00003030.00003020.00003010.0000302

型変換に失敗する参照が含まれていない場合

上の結果でいう100%だけを以下の数値設定で測りました。
count = 3000
length = 10000000

100%1回目2回目3回目平均
Cast73.951740574.002614374.110489574.0216148
AsIf81.379342881.517149181.494747781.4637465
IfIs81.909081582.200883581.964881182.0249487
IfIsCast93.986380794.081044187.086850991.7180919
IfIsAs93.911349394.215000587.068873391.7317410

()キャストは最速といっても気持ち速い程度のようです。
IfIsCastとIfIsAsは値が比較的安定していないので、実行状況によって速さが変わりやすいのかもしれません。


Viewing all articles
Browse latest Browse all 9509

Trending Articles