PowerShellでエクセルファイルを読んだら異常に遅かった

Windowsで日常作業の自動化をする時もperlを使うのが楽なので、ActivePerlが入ってればperlで行なうのですが、配布して他のサーバやパソコンで実行してもらうようなスクリプトだと、前提条件を無くしたいので、PowerShellも使えるようになっておきたいと思ってはいました。

入門としてとある作業のため、エクセルを読むスクリプトをPowerShellで書いてみたところ異常に遅くて困ってしまいました。

コード

エクセルファイルを読み込んで、A1からA100までのセルの値を足してechoするスクリプトを PowerShellとVB Scriptで用意しました。

$dir = Split-path -Parent $MyInvocation.MyCommand.Path
 
try {
    $excel = New-Object -ComObject Excel.Application
    $excel.Visible = $false
 
    $book = $excel.Workbooks.Open($dir + "\book.xlsx")
    $sheet = $book.Worksheets.Item(1)
    $sum = 0;
    for ($i = 1; $i -le 100; $i++) {
        $sum += $sheet.cells.Item($i, 1).Text
    }
    echo $sum
} catch {
    Write-Error("エラー" + $_.Exception)
} finally {
    $excel.Quit()
    $sheet, $book, $excel | foreach { $_ = $null }
}
Option Explicit
 
Dim fs
Set fs = CreateObject("Scripting.FileSystemObject")
Dim dir
dir = fs.GetParentFolderName(WScript.ScriptFullName)
 
Dim excel
Set excel = CreateObject("Excel.Application")
Dim book
Set book = excel.Workbooks.Open(dir & "\book.xlsx")
Dim sheet
Set sheet = book.Worksheets(1)
 
Dim i, sum
For i = 1 to 100
	sum = sum + sheet.Cells.Item(i, 1)
Next
WScript.Echo sum
 
excel.Quit
excel = null

計測

同じ条件になるように、以下の方法で実行時間を計測しました。

powershell -ExecutionPolicy RemoteSigned -C (Measure-Command { .\example.ps1}).TotalSeconds
powershell -ExecutionPolicy RemoteSigned -C (Measure-Command { cscript .\example.vbs}).TotalSeconds

それぞれ10回計測して平均した結果が以下です。

  • powershell 24.30305907 (s)
  • VB Script 1.10261345 (s)

22倍の差でVB Scriptの勝ちでした。 PowerShellもそこまで新しいものでもないから、ここまで遅い理由がわからないんですが、 PowerShellは、com objectを扱うのに適していない?またはコードの書き方に問題がある?

PowerShellは、コードの見た目が綺麗じゃなかったり、他の言語の欠点を普通にとりこんでたり、更には遅いとなると使うモチベーションが保てない…

One Comment

  • This post will help the internet people for setting up new weblog or even a weblog from start to end.

Leave a Comment

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.