週記くらい

  • Profile

Monthly Archives: April 2010

VBAでCollectionのループ方法をFor Eachに書き換えるだけで100倍高速になった

Posted on 2010/04/22 by smeghead

今、ExcelのVBAでちょっとしたものを作ってるのですが、コーディング中に急にパフォーマンスが悪くなるという現象が発生したので、原因を調べてみたらCollectionの各要素を処理する場面が問題のようだった。CollectionをFor Eachで周すようにしただけで、さっきの遅さが嘘のように解決してしまった。


本当にFor i = … のループを For Eachに書き換えただけで速くなるのか確信持てなかったし、他の原因も重なった結果かも、という疑惑も拭いきれない状態だったので、ExcelXPでベンチマークを取ってみました。

主要部分

下のLoop_for_indexとLoop_for_eachを比較しました。

'For i = ...版。 各要素を添字指定でアクセスする
Public Sub Loop_for_index()
  Dim dummy As Long
  Dim i As Long
  For i = 1 To list.Count
    Dim c As EmptyClass
    Set c = list(i)
    dummy = dummy + c.dummy
  Next
End Sub
 
'For Each版。 For Eachで直接アクセスする
Public Sub Loop_for_each()
  Dim dummy As Long
  Dim c As EmptyClass
  For Each c In list
    dummy = dummy + c.dummy
  Next
End Sub

'For i = ...版。 各要素を添字指定でアクセスする Public Sub Loop_for_index() Dim dummy As Long Dim i As Long For i = 1 To list.Count Dim c As EmptyClass Set c = list(i) dummy = dummy + c.dummy Next End Sub 'For Each版。 For Eachで直接アクセスする Public Sub Loop_for_each() Dim dummy As Long Dim c As EmptyClass For Each c In list dummy = dummy + c.dummy Next End Sub

結果

計測の結果、For Each版は、For i = …版より、100倍高速でした。

For Each版の方が速そうだと思っていたけど、100倍はいくらなんでも差がありすぎなんじゃないか?

For i = …版の書き方に問題があるんでしょうか?

もうちょっと調べてみると、単純に100倍というのは大袈裟で、Collectionの要素数が少ない(1000以下程度)場合は、数倍の差しかありませんでした。

とすると、問題はCollectionの要素が多い場合のFor i = …版の遅さか。

VBA使いの人には、あたり前の話なのかもというのも疑って、「vba for each 高速」で調べてみると、逆のことが書いてあるエントリを見つけて更に混乱してきた。

結論

コレクションに属する個々の要素を列挙する場合には「For~Next ステートメント」の方が「For Each~Next ステートメント」よりも高速である。

■T’sWare Access Labo #18 ~For~NextとFor Each~Nextを比較する~

単純に、「VBAで大量のデータを扱うな」という話なのかもしれない。


以下が、今回計測に使用した全スクリプトです。


EmptyClass

計測で利用するクラス。

Option Explicit
 
Public dummy As Integer

Option Explicit Public dummy As Integer

Timer

ミリ秒で計測するためのモジュール

Option Explicit
 
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
 
Public startTime As Long
 
Sub StopWatchStart()
  startTime = timeGetTime()
End Sub
 
Function StopWatchStop() As Long
  StopWatchStop = timeGetTime() - startTime
End Function

Option Explicit Private Declare Function timeGetTime Lib "winmm.dll" () As Long Public startTime As Long Sub StopWatchStart() startTime = timeGetTime() End Sub Function StopWatchStop() As Long StopWatchStop = timeGetTime() - startTime End Function

Module1

ベンチマークスクリプト

Option Explicit
 
Public list As Collection
 
'前処理 データの準備
Public Sub Setup()
  Set list = New Collection
  Dim i As Long
  Dim c As EmptyClass
  For i = 1 To 10000
    Set c = New EmptyClass
    Call list.Add(c)
  Next
End Sub
 
'For i = ...版。 各要素を添字指定でアクセスする
Public Sub Loop_for_index()
  Dim dummy As Long
  Dim i As Long
  For i = 1 To list.Count
    Dim c As EmptyClass
    Set c = list(i)
    dummy = dummy + c.dummy
  Next
End Sub
 
'For Each版。 For Eachで直接アクセスする
Public Sub Loop_for_each()
  Dim dummy As Long
  Dim c As EmptyClass
  For Each c In list
    dummy = dummy + c.dummy
  Next
End Sub
 
Public Sub main()
  Dim i As Integer
  Call Setup
  'Loop_for_index の実行
  For i = 1 To 10
    Call StopWatchStart
    Call Loop_for_index
    Debug.Print "Loop_for_index " & StopWatchStop & "ms"
  Next
  'Loop_for_each の実行
  For i = 1 To 10
    Call StopWatchStart
    Call Loop_for_each
    Debug.Print "Loop_for_each " & StopWatchStop & "ms"
  Next
End Sub

Option Explicit Public list As Collection '前処理 データの準備 Public Sub Setup() Set list = New Collection Dim i As Long Dim c As EmptyClass For i = 1 To 10000 Set c = New EmptyClass Call list.Add(c) Next End Sub 'For i = ...版。 各要素を添字指定でアクセスする Public Sub Loop_for_index() Dim dummy As Long Dim i As Long For i = 1 To list.Count Dim c As EmptyClass Set c = list(i) dummy = dummy + c.dummy Next End Sub 'For Each版。 For Eachで直接アクセスする Public Sub Loop_for_each() Dim dummy As Long Dim c As EmptyClass For Each c In list dummy = dummy + c.dummy Next End Sub Public Sub main() Dim i As Integer Call Setup 'Loop_for_index の実行 For i = 1 To 10 Call StopWatchStart Call Loop_for_index Debug.Print "Loop_for_index " & StopWatchStop & "ms" Next 'Loop_for_each の実行 For i = 1 To 10 Call StopWatchStart Call Loop_for_each Debug.Print "Loop_for_each " & StopWatchStop & "ms" Next End Sub

実行結果
Loop_for_index 329ms
Loop_for_index 293ms
Loop_for_index 298ms
Loop_for_index 294ms
Loop_for_index 297ms
Loop_for_index 291ms
Loop_for_index 294ms
Loop_for_index 294ms
Loop_for_index 294ms
Loop_for_index 296ms
Loop_for_each 3ms
Loop_for_each 3ms
Loop_for_each 3ms
Loop_for_each 3ms
Loop_for_each 3ms
Loop_for_each 2ms
Loop_for_each 3ms
Loop_for_each 3ms
Loop_for_each 3ms
Loop_for_each 3ms

Loop_for_index 329ms Loop_for_index 293ms Loop_for_index 298ms Loop_for_index 294ms Loop_for_index 297ms Loop_for_index 291ms Loop_for_index 294ms Loop_for_index 294ms Loop_for_index 294ms Loop_for_index 296ms Loop_for_each 3ms Loop_for_each 3ms Loop_for_each 3ms Loop_for_each 3ms Loop_for_each 3ms Loop_for_each 2ms Loop_for_each 3ms Loop_for_each 3ms Loop_for_each 3ms Loop_for_each 3ms

Posted in excel, vba | 9 Comments |

Starbug1 1.3.12 リリースのお知らせ

Posted on 2010/04/17 by smeghead

Starbug1は、軽量、高速なバグトラッキングシステム(BTS: Bug Tarcking System)です。

C で書かれているため少ないリソース(例えば10年前のパソコンなど)でも快適に動作します。

公式サイト http://starbug1.sourceforge.jp/

Sourceforge.jp http://sourceforge.jp/projects/starbug1/

Starbug1 1.3.12 をリリースしました。主な変更内容は以下です。

  • デフォルトのコンパイル方法をスタティック版にした。
  • テンプレート「TODO」で新規サブプロジェクトを作成した後、項目追加でエラーが出ていたのを修正した。
    • ここのコメントで教えていただいたバグです。henimarupeさん、報告ありがとうございました。
  • debug.logに書き込み権限が無い場合は、ログ出力しないようにしてエラーとはならないようにした。
    • 導入時のトラブルが減ります。
Posted in starbug1 | 3 Comments |

Starbug1 1.3.11 リリースのお知らせ

Posted on 2010/04/08 by smeghead

Starbug1は、軽量、高速なバグトラッキングシステム(BTS: Bug Tarcking System)です。

C で書かれているため少ないリソース(例えば10年前のパソコンなど)でも快適に動作します。

公式サイト http://starbug1.sourceforge.jp/

Sourceforge.jp http://sourceforge.jp/projects/starbug1/

Starbug1 1.3.11 をリリースしました。主な変更内容は以下です。

  • 64bit環境でも32bitコンパイルするようにした。
  • コンパイル時の言語を自動判定するようにした。(勿論今までのように指定することも可能)
  • デフォルトBTSに削除というステータスを追加した。(使い勝手の改良)
  • static版のバイナリを作成するmakefileのターゲットを追加した。
  • デザインの変更

簡単になったコンパイル方法

Starbug1のソースをダウンロードしたら、展開してから、make static webapp と打つだけで、動作モジュールが作成されるようになりました。依存しているライブラリ(cgic, sqlite3)をStarbug1のバイナリに含むようになるので、cgic、sqlite3をシステムにインストールする必要がありません。

f:id:smeghead:20100409005308p:image:right

デザイン更新

デザインを変えてみました。自分でもどうも納得できていない状態ですので、誰かデザインが得意な人、CSSファイルのパッチ募集中です。

64bit環境でのコンパイル

64bit環境でもコンパイルはできるのですが、sqlite3_prepare呼び出し時に、落ちる問題が発生したため、64bit環境の場合32bit互換でコンパイルするようにしました。

Thanks

static版のビルドのアイデアは、@fm021さんによるものです。そのまま取り込ませてもらいました。ありがとうございます。

でもsqliteは既に入っていたりして動的リンクだと競合しそうで試せない人もいるかもしれないので、手軽に利用するためにSqlite3とcgicを静的ビルド化して、ついでにSqlite3に10%程度高速らしいというamalgamation版を使ってみたメモです。

マキノ式ブログ » 超軽速BTSのStarbug1をamalgamation版Sqlite3で半生静的ビルドのメモ
Posted in starbug1 | 3 Comments |

Pages

  • Profile

Archives

  • September 2018
  • August 2018
  • March 2018
  • May 2015
  • February 2015
  • January 2015
  • December 2014
  • November 2014
  • October 2014
  • September 2014
  • April 2014
  • November 2013
  • October 2013
  • July 2013
  • April 2013
  • March 2013
  • February 2013
  • January 2013
  • December 2012
  • November 2012
  • October 2012
  • September 2012
  • August 2012
  • July 2012
  • June 2012
  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
  • February 2011
  • January 2011
  • December 2010
  • November 2010
  • October 2010
  • September 2010
  • August 2010
  • July 2010
  • June 2010
  • May 2010
  • April 2010
  • March 2010
  • February 2010
  • January 2010
  • December 2009
  • November 2009
  • October 2009
  • August 2009
  • July 2009
  • June 2009
  • May 2009
  • April 2009
  • March 2009
  • January 2009
  • December 2008
  • November 2008
  • October 2008
  • September 2008
  • August 2008
  • July 2008
  • June 2008
  • May 2008
  • April 2008
  • March 2008
  • February 2008
  • January 2008
  • December 2007
  • November 2007
  • October 2007
  • September 2007
  • August 2007
  • July 2007
  • June 2007
  • May 2007
  • April 2007
  • March 2007
  • February 2007
  • January 2007
  • December 2006
  • July 2006

Categories

  • android (35)
  • apache (1)
  • bison (1)
  • BTS (18)
  • c# (23)
  • cgi (1)
  • chrome (9)
  • chromeextention (18)
  • clclcl (9)
  • clojure (13)
  • cloudbug1 (2)
  • css (4)
  • cygwin (7)
  • C言語 (21)
  • dart (1)
  • dotnet (11)
    • vb.net (2)
  • e-hash.jp (1)
  • eclipse (2)
  • emacs (10)
  • excel (1)
  • flex (1)
  • framework (11)
  • free (93)
  • gae (4)
  • gcc (4)
  • gimmehash.in (1)
  • glipper (3)
  • golang (7)
  • howm (1)
  • html (3)
  • ikushipe (1)
  • java (47)
  • JavaScript (29)
  • linux (16)
  • lisp (92)
  • lua (34)
  • luatinycgi (2)
  • mba (1)
  • Meadow (4)
  • memo (1)
  • music (5)
  • mysql (2)
  • neta (5)
  • node (2)
  • O/Rマッピングツール (4)
  • obj-c (6)
  • OOP (6)
  • oracle (1)
  • perl (49)
  • php (38)
    • CakePHP2 (2)
  • PostgreSQL (8)
  • PowerShell (1)
  • putty (1)
  • python (14)
  • redmine (2)
  • ruby (7)
  • s3 (1)
  • sakura (5)
  • screen (1)
  • Selenium (1)
  • SF (1)
  • SKK (4)
  • slime (6)
  • sql (8)
  • sqlite3 (4)
  • starbug1 (179)
  • tthttpd (3)
  • twitter (8)
  • ubuntu (14)
  • Uncategorized (4)
  • unix (14)
  • unkode-mania (5)
  • vba (3)
  • vim (24)
  • w3m (1)
  • Windows (17)
  • wordpress (1)
  • zsh (6)
  • 愚痴 (1)

WordPress

  • Log in
  • WordPress

Subscribe

  • Entries (RSS)
  • Comments (RSS)

Pages

  • Profile

Archives

  • September 2018
  • August 2018
  • March 2018
  • May 2015
  • February 2015
  • January 2015
  • December 2014
  • November 2014
  • October 2014
  • September 2014
  • April 2014
  • November 2013
  • October 2013
  • July 2013
  • April 2013
  • March 2013
  • February 2013
  • January 2013
  • December 2012
  • November 2012
  • October 2012
  • September 2012
  • August 2012
  • July 2012
  • June 2012
  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
  • February 2011
  • January 2011
  • December 2010
  • November 2010
  • October 2010
  • September 2010
  • August 2010
  • July 2010
  • June 2010
  • May 2010
  • April 2010
  • March 2010
  • February 2010
  • January 2010
  • December 2009
  • November 2009
  • October 2009
  • August 2009
  • July 2009
  • June 2009
  • May 2009
  • April 2009
  • March 2009
  • January 2009
  • December 2008
  • November 2008
  • October 2008
  • September 2008
  • August 2008
  • July 2008
  • June 2008
  • May 2008
  • April 2008
  • March 2008
  • February 2008
  • January 2008
  • December 2007
  • November 2007
  • October 2007
  • September 2007
  • August 2007
  • July 2007
  • June 2007
  • May 2007
  • April 2007
  • March 2007
  • February 2007
  • January 2007
  • December 2006
  • July 2006

Categories

  • android (35)
  • apache (1)
  • bison (1)
  • BTS (18)
  • c# (23)
  • cgi (1)
  • chrome (9)
  • chromeextention (18)
  • clclcl (9)
  • clojure (13)
  • cloudbug1 (2)
  • css (4)
  • cygwin (7)
  • C言語 (21)
  • dart (1)
  • dotnet (11)
    • vb.net (2)
  • e-hash.jp (1)
  • eclipse (2)
  • emacs (10)
  • excel (1)
  • flex (1)
  • framework (11)
  • free (93)
  • gae (4)
  • gcc (4)
  • gimmehash.in (1)
  • glipper (3)
  • golang (7)
  • howm (1)
  • html (3)
  • ikushipe (1)
  • java (47)
  • JavaScript (29)
  • linux (16)
  • lisp (92)
  • lua (34)
  • luatinycgi (2)
  • mba (1)
  • Meadow (4)
  • memo (1)
  • music (5)
  • mysql (2)
  • neta (5)
  • node (2)
  • O/Rマッピングツール (4)
  • obj-c (6)
  • OOP (6)
  • oracle (1)
  • perl (49)
  • php (38)
    • CakePHP2 (2)
  • PostgreSQL (8)
  • PowerShell (1)
  • putty (1)
  • python (14)
  • redmine (2)
  • ruby (7)
  • s3 (1)
  • sakura (5)
  • screen (1)
  • Selenium (1)
  • SF (1)
  • SKK (4)
  • slime (6)
  • sql (8)
  • sqlite3 (4)
  • starbug1 (179)
  • tthttpd (3)
  • twitter (8)
  • ubuntu (14)
  • Uncategorized (4)
  • unix (14)
  • unkode-mania (5)
  • vba (3)
  • vim (24)
  • w3m (1)
  • Windows (17)
  • wordpress (1)
  • zsh (6)
  • 愚痴 (1)

WordPress

  • Log in
  • WordPress

CyberChimps WordPress Themes

© 週記くらい@やーづ

With Google+ plugin by Geoff Janes