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 件のコメント:
コメントを投稿