VB.NET/.NetFramwork2で型変換の速度差、特色について気になりだしたので、実験してみました。
興味があった変換は、普段よく使う
- Object→Int32への変換
- String→Int32への変換
です。
実験したものはCtype、CInt、DirectCast、Convert.ToInt32、Int32.Parse、 Int32.TryParse。
実験結果としてはこんな感じです。【 】の中の数値はObjectなりStringなりのmyData変数を、それぞれのメソッドなりでの変換したものです。Int32.TryParseで【 0】となっているのは、変換できなかったということですね。
実験結果
(速度の早い順に並び替え)Dim my_Data As Object = 12345 DirectCast : 【 12345】00:00:00.0004363 CInt : 【 12345】00:00:00.0023329 'CtypeとCInt、Convert.ToInt32は順位が入れ替わるときがあります。 CType : 【 12345】00:00:00.0023815 Convert.ToInt32 : 【 12345】00:00:00.0030900 Int32.Parse : 【 12345】00:00:00.0468925 'Int32.ParseとInt32.TryParseは順位が入れ替わるときがあります。 Int32.TryParse : 【 12345】00:00:00.0475714 Dim my_Data As Object = 12345.5 CInt : 【 12346】00:00:00.0039555 CType : 【 12346】00:00:00.0040038 Convert.ToInt32 : 【 12346】00:00:00.0052587 Int32.TryParse : 【 0】00:00:00.0631435 Dim my_Data As String = "12345" Int32.Parse : 【 12345】00:00:00.0198393 Int32.TryParse : 【 12345】00:00:00.0206115 Convert.ToInt32 : 【 12345】00:00:00.0214960 CType : 【 12345】00:00:01.7970309 CInt : 【 12345】00:00:01.7990923 Dim my_Data As String = "12345.5" Int32.TryParse : 【 0】00:00:00.0198050 CInt : 【 12346】00:00:01.8433437 CType : 【 12346】00:00:01.8474300
所感としては、Object型のときは、DirectCastを使うのが一番高速(但しDirectCastは丸め処理などは行わず、Int32に変換するのに小数などを引数に渡すとエラーを吐きます)。String型のときは、Int32.Parseが一番高速…、というところでしょうかね。現実問題としてはInt32.TryParseも、使い勝手がよさそうです。
サンプルソース
※Int32.Parseの引数はもともとString型なので、Option StrictはOffにしないと走りません。
Imports System.Diagnostics Public Class Form1 Private Sub Button1_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles Button1.Click Dim sw As New Stopwatch Dim sb_Data As New System.Text.StringBuilder Dim bl_result As Boolean Dim my_Dict As New Dictionary(Of String, String) Dim my_Data As Object = 12345 '#---ここをあれこれ差し替えました。 ' 少数の値をセットしたりして ' エラーができるときは、 ' 型変換部分も ' コメントアウトします。 Dim int_Data As Int32 '---------------------------------- sw.Reset() sw.Start() For i As Int32 = 0 To 100000 int_Data = CType(my_Data, Int32) Next sw.Stop() my_Dict.Add("CType" & vbTab _ & int_Data.ToString, _ sw.Elapsed.ToString) '---------------------------------- sw.Reset() sw.Start() For i As Int32 = 0 To 100000 int_Data = CInt(my_Data) Next sw.Stop() my_Dict.Add("CInt" & vbTab _ & int_Data.ToString, _ sw.Elapsed.ToString) '---------------------------------- sw.Reset() sw.Start() For i As Int32 = 0 To 100000 int_Data = DirectCast(my_Data, Int32) Next sw.Stop() my_Dict.Add("DirectCast" & vbTab _ & int_Data.ToString, _ sw.Elapsed.ToString) '---------------------------------- sw.Reset() sw.Start() For i As Int32 = 0 To 100000 int_Data = Convert.ToInt32(my_Data) Next sw.Stop() my_Dict.Add("Convert.ToInt32" & vbTab _ & int_Data.ToString, _ sw.Elapsed.ToString) '---------------------------------- sw.Reset() sw.Start() For i As Int32 = 0 To 100000 int_Data = Int32.Parse(my_Data) Next sw.Stop() my_Dict.Add("Int32.Parse" & vbTab _ & int_Data.ToString, _ sw.Elapsed.ToString) '---------------------------------- sw.Reset() sw.Start() For i As Int32 = 0 To 100000 bl_result = Int32.TryParse(my_Data, _ int_Data) Next sw.Stop() my_Dict.Add("Int32.TryParse" & vbTab _ & int_Data.ToString, _ sw.Elapsed.ToString) '---------------------------------- Dim sorted As List(Of KeyValuePair(Of String, String)) _ = sortByValue(my_Dict) sorted.Reverse() For Each kvp As KeyValuePair(Of String, String) In sorted Dim str_SPL() As String _ = kvp.Key.Split(vbTab.ToCharArray) Dim str_Num As String _ = Strings.StrDup(10, " ") & str_SPL(1) sb_Data.Append((str_SPL(0) & " :" _ & Strings.StrDup(20, " ")).Substring(0, 20) _ & "【" & (str_Num).Substring(str_Num.Length - 10, 10) & "】" _ & kvp.Value & vbCrLf) Next Me.TextBox1.Text = sb_Data.ToString sb_Data.Remove(0, sb_Data.Length) sb_Data = Nothing End Sub Shared Function hikaku(Of TKey, TValue As IComparable(Of TValue))( _ ByVal kvp1 As KeyValuePair(Of TKey, TValue), _ ByVal kvp2 As KeyValuePair(Of TKey, TValue)) As Integer Return kvp2.Value.CompareTo(kvp1.Value) End Function Shared Function sortByValue(Of TKey, TValue As IComparable(Of TValue))( _ ByVal dict As Dictionary(Of TKey, TValue)) _ As List(Of KeyValuePair(Of TKey, TValue)) Dim list As New List(Of KeyValuePair(Of TKey, TValue))(dict) 'Valueの大きい順にソート list.Sort(AddressOf hikaku) Return list End Function End Class
0 件のコメント:
コメントを投稿