VB ArrayList,LIST(Of T),配列 比較
VisualBasic6.0やVBAからVB.NETに移行してきた方はたいていの場合「配列使い」ですよね。しかしVB.NETだと,もはや配列は古い概念であって今は「ArrayList」なんだ,とか,いやいやArrayListも昔の話で今は「ジェネリック(List(Of
T))」なんだよ,とかネットで散見されます。
このArrayList,List(Of T)が最初につまずくポイントの1つでなかなか身につきません。
ところで,CSVファイルを読み込むサンプルコードを改めて探していたところ,いつもお世話になっているサイトにいつものように載っていました。
「CSV形式のファイルをDataTableや配列等として取得する」
で,このサンプルコードの出力がArrayListになっています。
そのコードをあまり気にせず流用させて頂いていたのですが,CSVデータを計算させる自作クラスが元々,2次元配列前提だったためArrayList用に全部コードを直すか,またはデータをArrayListから2次元配列に変換するか,のどちらかの対応が必要になりました。
しかし,そもそもArrayListってもう古いんじゃなかったっけ?
ArrayListはオブジェクトとしてデータを扱うのでキャストがかかり遅くなるって書いてあるし。
となると,直すにしてもList(Of T)だろうし,でも,もしかして配列の方が高速なのでは?
と頭の中が収拾つかなくなったため,実験して方向性を決めることにしました。
まず10万行,5列,カンマ区切りのCSVファイルを用意し,ArrayList,List(Of T),ジャグ配列のそれぞれでファイルを読み込む時間を計測,さらに読み込んだArrayList,List(Of T),ジャグ配列,2次元配列(2次元配列は複製)のデータを変数に代入する時間をそれぞれ計測し比較してみました。
結果 (時間は秒)
項目 | CSV読み込み | 変数に代入 | ArrayList比 |
ArrayList | 1.883 | 1.4262 | |
List(Of T) | 1.907 | 0.0066 | 217倍 |
ジャグ配列 | 1.858 | 0.0037 | 388倍 |
2次元配列 | - | 0.0057 | 248倍 |
CSV読み込みはArrayList,List(Of T),ジャグ配列とも同じプログラムコードでかつ3.3MByteもあるファイルを読み込んでいるためか差がないように見えます。対して変数への代入はArrayListだけがすごく遅いことが分かりました。
結論
1)ArrayListは使用しない。
2)検索やソート無しの単純な使用,かつ速度最優先ならジャグ配列。
3)上記2項以外は用途に応じて普通の配列かList(Of T)。
ArrayListは要素がObjectのために遅いのですが,逆に何でもありのObjectだからこそ利点になることもあるようです。
なお,上記計測は変数への代入時間ですが,2次元配列に代入した場合も計測しておりList(Of T),ジャグ配列,2次元配列とも倍程度の時間が掛かっていました。
それからDataTableと言うのもありますが,それも遅いですので用途次第での活用となります(自分でも検証済み)。
「意外と遅い DataTable 、なので List を使うと 5 倍早くなる」
List(Of T)の最大の利点は要素数を気にしなくて良いことですが,改めて自分のプログラムコードを眺めると配列宣言で要素数を決め打ちしたり,結構ReDimしていたりで後々のメンテがいま一つ,かつロスっていますのでList(Of T)の活用は非常に有効です。
さて,食わず嫌いを止めて腕まくりしますか…
検証に使用したVisualBasicのソースコード
-----------------------------------------------------------
Imports System.Collections
Imports System.Collections.Generic
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs)_
Handles Button1.Click
Dim sw As New System.Diagnostics.Stopwatch()
Dim csvFileName As String = "D:\Work\test.csv"
'3月16日,54315,3315,131315,10.432 のようなデータを10万行
Dim csvData1 As New ArrayList() 'ArrayList
Dim csvData2 As New List(Of String()) 'List(Of T)
Dim csvData3()() As String 'ジャグ配列
Dim loop1 As Integer
Dim loop2 As Integer
Dim dummyStr As String = ""
'ArrayListでCSV読み込み
sw.Start()
csvData1 = csvLoad_ArrayList(csvFileName)
sw.Stop()
Console.WriteLine(sw.Elapsed)
sw.Reset()
'List(Of T)でCSV読み込み
sw.Start()
csvData2 = csvLoad_List(csvFileName)
sw.Stop()
Console.WriteLine(sw.Elapsed)
sw.Reset()
'ジャグ配列でCSV読み込み
sw.Start()
csvData3 = csvLoad_Array(csvFileName)
sw.Stop()
Console.WriteLine(sw.Elapsed)
sw.Reset()
'ArrayListから変数に代入
sw.Start()
For loop1 = 0 To csvData1.Count - 1
For loop2 = 0 To csvData1(loop1).length - 1
dummyStr = csvData1(loop1)(loop2)
Next loop2
Next loop1
sw.Stop()
Console.WriteLine(sw.Elapsed)
sw.Reset()
'List(Of T)から変数に代入
sw.Start()
For loop1 = 0 To csvData2.Count - 1
For loop2 = 0 To csvData2(loop1).Length - 1
dummyStr = csvData2(loop1)(loop2)
Next loop2
Next loop1
sw.Stop()
Console.WriteLine(sw.Elapsed)
sw.Reset()
'ジャグ配列から変数に代入
sw.Start()
For loop1 = 0 To csvData3.GetLength(0) - 1
For loop2 = 0 To csvData3(loop1).Length - 1
dummyStr = csvData3(loop1)(loop2)
Next loop2
Next loop1
sw.Stop()
Console.WriteLine(sw.Elapsed)
sw.Reset()
'ジャグ配列から2次元配列を複製
Dim row As Integer = csvData3.GetLength(0) - 1
Dim col As Integer = csvData3(0).Length - 1
Dim csvData4(row, col) As String
For loop1 = 0 To csvData3.GetLength(0) - 1
For loop2 = 0 To csvData3(loop1).Length - 1
csvData4(loop1, loop2) = csvData3(loop1)(loop2)
Next loop2
Next loop1
'2次元配列から変数に代入
sw.Start()
For loop1 = 0 To csvData4.GetLength(0) - 1
For loop2 = 0 To csvData4.GetLength(1) - 1
dummyStr = csvData4(loop1, loop2)
Next loop2
Next loop1
sw.Stop()
Console.WriteLine(sw.Elapsed)
sw.Reset()
Application.Exit()
End Sub
Private Function csvLoad_ArrayList(csvFileName As String)
'ArrayListでCSVファイル読み込み
Dim csvRecords As New ArrayList()
Dim tfp As New FileIO.TextFieldParser(csvFileName, _
System.Text.Encoding.GetEncoding(932))
tfp.TextFieldType = FileIO.FieldType.Delimited
tfp.Delimiters = New String() {","}
tfp.HasFieldsEnclosedInQuotes = True
tfp.TrimWhiteSpace = True
While Not tfp.EndOfData
Dim fields As String() = tfp.ReadFields()
csvRecords.Add(fields)
End While
tfp.Close()
Return csvRecords
End Function
Private Function csvLoad_List(csvFileName As String)
'List(Of T)でCSVファイル読み込み
Dim csvRecords As New List(Of String())
Dim tfp As New FileIO.TextFieldParser(csvFileName, _
System.Text.Encoding.GetEncoding(932))
tfp.TextFieldType = FileIO.FieldType.Delimited
tfp.Delimiters = New String() {","}
tfp.HasFieldsEnclosedInQuotes = True
tfp.TrimWhiteSpace = True
While Not tfp.EndOfData
Dim fields As String() = tfp.ReadFields()
csvRecords.Add(fields)
End While
tfp.Close()
Return csvRecords
End Function
Private Function csvLoad_Array(csvFileName As String)
'List(Of T)でCSVファイルを読み込みジャグ配列に変換
Dim csvRecords()() As String
Dim dummyRecords As New List(Of String())
Dim tfp As New FileIO.TextFieldParser(csvFileName, _
System.Text.Encoding.GetEncoding(932))
tfp.TextFieldType = FileIO.FieldType.Delimited
tfp.Delimiters = New String() {","}
tfp.HasFieldsEnclosedInQuotes = True
tfp.TrimWhiteSpace = True
While Not tfp.EndOfData
Dim fields As String() = tfp.ReadFields()
dummyRecords.Add(fields)
End While
tfp.Close()
csvRecords = dummyRecords.ToArray
Return csvRecords
End Function
End Class
| 固定リンク
この記事へのコメントは終了しました。
コメント
<a href=https://lindera.ru/>Здесь</a>
投稿: Rogerviedo | 2021年6月10日 (木) 05時56分
Young Heaven - Naked Teens & Young Porn Pictures
http://bellathornegf.allproblog.com/?moriah
grab porn tube bi couple porn your amatuer porn dump sex doggy style porn pics hoemade porn
投稿: hollyoy18 | 2021年11月11日 (木) 05時49分