Memorandum

速度比較検証

VBAから扱えるDLLを作成したいと思い、Visual Studio 2017を利用しつくってみました。
参考:[VBAから扱えるDLLを作成] [VBAをVBに変換]
作成したのは数独を解析するDLLファイルです。VBAコード:Excelで数独解析 Ver.2.3.0

そもそも、なぜVBAから扱えるDLLを作成したのかは、数独をより高速に解析したいと考えたからです。 [世界最速への挑戦]
VBAはインタプリタ型言語(プログラム実行時にコードを機械語に翻訳する形式のプログラム)なので、コンパイラ型言語(予めコードを機械語に翻訳する形式のプログラム)より、実行速度が遅いと言われています。
DLLファイルは、コンパイルされているので、同じ内容であれば、VBAよりプログラムの実行速度が速くなることが期待されます。

無事にDLLができたので、どのくらい速くなるのかを検証してみました。
そのまとめのメモです。

検証内容

・数独の250問連続解析 ver.2.3.0
・VBAコードの速度とDLLファイルコードの速度を比較

※検証の前提・・・Windows 10 / Intel(R) Core(TM) i7-3517U CPU 2.40GHz / Excel2007


VBAコード検証

検証用ファイル:検証を行ったExcelファイル。クリックでダウンロード。
検証・解析コード:検証コード。抜粋したものを以下に表示。
※本来の250問解析ファイルは、VBAで準備されているTimer関数を使っている。今回はより正確な時間の計測を行うため、Win32APIのtimeGetTime関数を使用した。

#If VBA7 Then 'Excel2010以上
    Declare PtrSafe Function timeGetTime Lib "winmm.dll" () As Long
#Else 'Excel2007以下
    Declare Function timeGetTime Lib "winmm.dll" () As Long
#End If

Type TTT
    varValue(1 To 9, 1 To 9) As Variant
    varKai As Variant
End Type
 
Public TB(1 To 250) As TTT

Sub Sample250() Dim i As Long, j As Long Dim ii As Long, jj As Long Dim lngTime As Long Dim strS As String Dim varVal As Variant With Application .ScreenUpdating = False With Worksheets(1) varVal = .Range("B1:J2250").Value For i = 1 To 250 ii = (i - 1) * 9 For j = 1 To 9 For jj = 1 To 9 TB(i).varValue(j, jj) = varVal(ii + j, jj) Next Next TB(i).varKai = TB(i).varValue Next lngTime = timeGetTime() For i = 1 To 250 If Sudoku_Kaiseki(TB(i).varKai, strS, True) <> 0 Then MsgBox strS, vbExclamation + vbOKOnly, i & "問目": Exit Sub End If Next MsgBox timeGetTime() - lngTime & "ミリ秒" For i = 1 To 250 ii = (i - 1) * 9 For j = 1 To 9 For jj = 1 To 9 varVal(ii + j, jj) = TB(i).varKai(j, jj) Next Next Next .Range("L1:T2250").Value = varVal End With .ScreenUpdating = True End With End Sub
Sub Syoukyo250() Worksheets(1).Range("L1:T2250").ClearContents End Sub

[ 結果 ]

VBAコードでの結果:250問解析に要した時間、217ミリ秒(0.217秒)


DLLファイル検証

検証用ファイル:検証用ファイル一式(Excel、DLLファイル他)。クリックでダウンロード
ダウンロード時に警告がでるかもしれないが問題ない。警告はVBスプリクトファイルが含まれているため。
検証・解析コード:検証コード。VBAからDLLにアクセス。以下に表示。
※予め、DLLを登録する必要がある。同梱されているファイルで簡単に行える。DLLの登録
このDLLファイルは、64bit版のExcelには対応していない。

#If VBA7 Then 'Excel2010以上
    Declare PtrSafe Function timeGetTime Lib "winmm.dll" () As Long
#Else 'Excel2007以下
    Declare Function timeGetTime Lib "winmm.dll" () As Long
#End If

Type TTT
    varKai(9, 9) As Long
End Type
 
Public TB(1 To 250) As TTT

Sub Sample250() Dim i As Long, j As Long Dim ii As Long, jj As Long Dim lngTime As Long Dim strS As String Dim varVal As Variant Dim clsSudoku As New Sudoku_Kaiseki.analysis_sudoku With Application .ScreenUpdating = False With Worksheets(1) varVal = .Range("B1:J2250").Value For i = 1 To 250 ii = (i - 1) * 9 For j = 1 To 9 For jj = 1 To 9 TB(i).varKai(j, jj) = varVal(ii + j, jj) Next Next Next lngTime = timeGetTime() For i = 1 To 250 If clsSudoku.Sudoku_Kaiseki_Main(TB(i).varKai, strS, True) <> 0 Then MsgBox strS, vbExclamation + vbOKOnly, i & "問目": Exit Sub End If Next MsgBox timeGetTime() - lngTime & "ミリ秒" For i = 1 To 250 ii = (i - 1) * 9 For j = 1 To 9 For jj = 1 To 9 varVal(ii + j, jj) = TB(i).varKai(j, jj) Next Next Next .Range("L1:T2250").Value = varVal End With .ScreenUpdating = True End With End Sub
Sub Syoukyo250() Worksheets(1).Range("L1:T2250").ClearContents End Sub

[ 結果 ]

DLLファイルを利用の結果:250問解析に要した時間、31ミリ秒(0.031秒)


まとめ

インタプリタ型であるVBAと、コンパイラ型のDLLファイルを、ほぼ同じ内容の処理で比較した結果、私の環境ではDLLファイルの方が約7倍速い結果となった。

今回検証に用いた数独と同難度の問題を、私のパソコン環境で解析を行う場合、理論上、VBAのみの場合は1秒間に1152問、DLLを用いると1秒間に8064問解析ができることがわかった。

※VBAとDLLの解析コードを比較しながら見る場合はこちら。コード比較 左[VB] 右[VBA]


DLLファイルの使用

DLLファイル検証の検証用ファイルに入っているDLLはご自由にご使用いただいて構いません。ただし、無許可での配布等はやめてください。連絡はこちら
同梱されているスクリプトファイルを用い、一度登録すると、Excelからいつでも数独を解析する関数を呼び出すことができます(用途は限定されていますが。。。)。

※ダウンロード時に警告がでるかもしれないが問題ない。警告はVBスプリクトファイルが含まれているため。
同梱されている説明書

ページトップへ戻る
Copyright(C) 2009- 坂江 保 All Rights Reserved.