Excel-DNA で XLL をつくる(その6)

 Excel-DNA で簡単に XLL を作成できることはわかりました。XLL アドインはワークシート上でユーザー定義関数として直接利用できて便利ですね。これが VBA からも利用できると便利です。XLL アドインに定義された関数をVBAから利用する方法は、ここに説明されています。→ (MSDN) Accessing XLL Code in Excel
 これによると、Application.Run メソッドで行えることがわかります。さっそく、コードを書いて試してみます。こんなコードを書いてみました(笑)
(こんな感じ↓)

<DnaLibrary RuntimeVersion="v4.0" Name="Prime" Language="CS">
<!&#91;CDATA&#91;

using System.Threading.Tasks;
public class Prime
{
        public static bool IsPrime(int x)
        {
            for (int i = 2; i <= x / 2; i++)
            {
                if (x % i == 0)
                {
                    return false;
                }
            }
            return true;
        }
}
&#93;&#93;>
</DnaLibrary>

 与えられた整数 x が素数であるか?判定する関数です。あの・・・、アルゴリズムに突っ込んではいけません。与えられた整数 x より小さな整数でひたすら割り切れるかどうかチェックします(笑)
 上記のコードを、.dna ファイルに記述し、実行してみましょう。シート上に =IsPrime(A1) のように記述すると、ちゃんと動作してますね。
では、VBA から呼んでみます。ただ呼んでも面白くないので、同じ処理を行う VBA コードを書いて、処理速度を比較してみたいと思います。上記のコードを VBA で記述するとこうなりますね?

Function IsPrimeVBA(target As Long) As Boolean
Dim i As Long
    IsPrimeVBA = True
    For i = 2 To target / 2
        If target Mod i = 0 Then
            IsPrimeVBA = False
            Exit For
        End If
    Next
End Function


 これを、Excel-VBE で標準モジュールを作成して記述します。これで、ワークシートからユーザー定義関数として、=IsPrimeVBA(A1) のように呼べますね。これで、準備が出来ました。VBA からそれぞれの関数を呼んで、処理時間を計測してみましょう。こんなコードを書いてみました。

Sub VBACalculateTime()
Dim start, finish
Dim is_prime As Boolean
With ActiveSheet

    start = Timer
        is_prime = Application.Run("IsPrime", .Range("A1").Value)
    finish = Timer
    Debug.Print (is_prime & ":XLL time= " & finish - start)
    
    start = Timer
        is_prime = IsPrimeVBA(.Range("A1").Value)
    finish = Timer
    Debug.Print (is_prime & ":VBA time= " & finish - start)
    
End With
End Sub

 このコードでは、ワークシートのA1セルに入っている数値を素数判定する時間を計測します。小さな数値では差がわかりにくいかもしれませんので、Long の最大値(2147483647)を入れてみることにしましょう。2147483647 は都合のいいことに素数なので、これの判定を行うにはかなりの繰り返し演算が必要になります。

 いかがでしたか?私の環境では、かなり差が出ました。そして、会社のExcel2007(x86) と自宅のExcel2010(x64)で比較したところ・・・ふしぎな事に、XLL の関数の処理時間はほぼ同じなのに対して、VBA で作成した関数はExcel2010(x64) のほうが約2倍の処理時間となりました。どうしてなんでしょうね~?
どなたかご存知の方がおられたら、教えてください。

 しかし、XLL だと、COMアドインのようにオブジェクトの生成が出来ないのがたまにきずですね♪
次回は、ちょっとExcel-DNA から離れて、以前に作成した BigIntXLL.dll を、COMアドイン および、COMオートメーションアドイン として登録してみたいと思います。で・・・、 VBA vs COM vs XLL の処理時間を比較してみたいとおもいます♪

では、また(笑)

This entry was posted in Excel, .NetFramework and tagged , . Bookmark the permalink.

6 Responses to Excel-DNA で XLL をつくる(その6)

  1. y sakuda says:

    VBAの方だけやってみました。
    Vista+2007でも2010で両方共約30秒で差がでません。

    • supermab says:

      >VBAの方だけやってみました。

      ありがとうございます m(_ _)m

      >Vista+2007でも2010で両方共約30秒で差がでません。

      XP+Excel2007(x86)+Core2 Quad だと23秒
      Win7(x64) + Excel2010(x64) + i5 だと・・・46秒なんです。
      ちょうど2倍違います。

      XLL のほうは、どちらも約 5秒 なんですが・・・(謎)

  2. y sakuda says:

    >XLL のほうは、どちらも約 5秒 なんですが・・・(謎)
    うーーん速いですね。
    明日でもまたやって見ます。

  3. y sakuda says:

    Vista+2007,2010でDNAもやってみました。
    2007:DNA 7.5秒、VBA 29.2秒
    2010:DNA 6.8秒、VBA 29.7秒
    で2007、2010で特に差があるとは思えません。
    しかし、DNAの方もインタープリティブにやってるはずですが、早いですね。

    • supermab says:

      >で2007、2010で特に差があるとは思えません。

      ん・・・
      PCの違いですかね~?
      なんか、CPU の違いが疑わしいところです。
      でも、XLL のほうはあまり変わらないので・・・
      やはり、謎です^^

  4. y sakuda says:

    ついでに2003でもやってみました。
    やはり、DNA:6.9~8.4、VBA:29.4 でほぼ2007以降と変わりませんね。

Leave a Reply

Your email address will not be published. Required fields are marked *