2006-06-13 15:55:18
.Netアプリケーションの起動が遅いことについて
テーマ:.Net & C# Tips
今回はTIPと言えるかどうかはちょっと疑問ですが、.Net Frameworkを利用したアプリケーションの起動が遅いことについてちょっと遊んでみました。
そもそも.Netアプリケーションは遅いってイメージを私も持ってましたけど、起動後は気になるほどの遅さじゃないですよね。まあ、たしかにネイティブコンパイルされたアプリよりは若干遅いですが。よほど高速な動作をもとめられるアプリじゃないかぎり問題ないのではないと最近感じてます。
ただし、起動は遅い。これは確かにそうだ。そう感じる。 と常々思っていたのですが、今回今更ながらまともに調べてみました。
それでわかったことは、今まで私はVS等で出力される中間コードであるMSIL(Microsoft Intermediate Language)をユーザーのPCでJIT(Just-In-Time)コンパイラでネイティブコンパイルするのが遅いものだと思ってました。でも実はよほど大きなプログラムじゃないかぎりJITは思ってたより遅くないですね。(もちろん早くは無いけどね)
それよりも.NetFrameWork自体の起動がやたら長く感じるのが原因ってことが良くわかりました。(← 間違えてたらごめん) しかも遅いってのもさることながら.NetFrameWorkの起動中になにも表示されないから、なにしてるのか気になるし、クリック失敗したかな?と思って重複起動してさらに遅くなるし、、、ってのでイライラしちゃうんですよね。なんかイメージとして「もたぁ~~~」っとした起動に感じるんです。
ユーザーのPCでJITする時間はインストール時とかにngen使ってプレコンパイルしてイメージ化しておけば、ある程度緩和できるはずですが、管理者権限が必要だとか、効果は微妙でプログラムの内容によっては効果がなかったり、場合によっては動作効率悪くなったり、その上結局.NetFrameWorkの起動時間は必要ってので、あまり期待できないですね。他の人のそういう意見も聞きますし。
ってことで、んじゃどうしようかと考えていたのですが、とりあえず、ぱっと思いつくのは3つでした。
1、次期Windowsを待つ。.NetFrameWork対応とのことなので、この辺も改善されると予想する。希望する。なれ!
2、PCの起動時(スタートアップ)に非表示の.Netアプリケーションを起動して常駐する。これによって.NetFrameWorkは既に起動されているのでその後の.Netアプリケーションの起動時間が少なくなるはず。
3、アンマネージドでネイティブコンパイル済みのスプラッシュ・スクリーン表示して.Netアプリケーションを起動するプログラムを作成する。これにより体感速度の向上と無意味な重複起動のリスクを削減。
ってな感じです。
とりあえず1については今はどうしようもないし、直ぐに全員が移行するわけではないので、却下。しょうがない。
2と3については改善される可能性はあるが、どっちにするかはそのアプリケーションの内容次第と言ったところでしょうか。
3は根本的な解決にならないので開発者の目の届く範囲で、且つ.NetFrameWorkを理解しているユーザーの場合には2が有効ではないかと思います。逆に2は不特定多数の一般ユーザーが対象だとユーザーは気持ち悪いと思うかもしれないし、無駄なリソースを取られるのでうざいと思われても仕方が無いかも、、、PCの起動が遅くなるわけですから。
3は根本的な解決とは程遠いですが、場合によって体感がかなり違うので不特定多数の一般ユーザーには優しいと思われます。(解決じゃなくて誤魔化し?) まあ、でもスプラッシュスクリーン自体が好まれているわけではないので、これも使いどころですね~。
ということで早速3を試して見ました。
以下、私がやった概要
####################################################################
初めにアンマネージドC++でスプラッシュ・スクリーン表示して.Netアプリケーションを起動するプログラムを作成します。
(私はC++が得意じゃないので、作り方の詳細は検索で調べてくださいね。)
私の場合はわざわざVC++6でMFCアプリケーションウィザードでSDIでMFCスタティックライブラリを使用するアプリケーションをウィザード通りに作成して、「プロジェクト>プロジェクトへ追加>コンポーネントおよびコントロール」からVisual C++ Componentsの中にあるスプラッシュスクリーンを追加して、あとはいらないコードをチェックしながら削除していきました。
これでスプラッシュ・スクリーンを追加されたので、あとは.Netアプリケーションを起動するだけです。ちなみに他アプリの起動はInitInstance()内に
[ShellExecute(NULL, "open", "appname.exe", NULL, NULL, SW_SHOW);]
こんな感じで追加しました。これで一応完成。
尚、私は通常VS2005で開発してるので、このプロジェクトをVC2005に取り込みました。
そしたらなんと完成物のサイズがなんと2倍に、、、、なぜだ、、、MFCが違うのか???
ちなみに私の場合ですとこのアプリが400kあります。これっぽっちのアプリに400kはちょっと凹みました。とはいっても5,6割はbitmapとiconの重さですけどね。
あとはスプラッシュ・スクリーンがどのタイミングで消えるのかっていうことですが、
私の場合には開く方側のアプリでは閉じないで、.Netアプリが起動したら.Netアプリ側から起動元のアプリを閉じるようにしました。
こんな感じ (C#)
----------------------------------------------------------------------
System.Diagnostics.Process[] hProcesses = System.Diagnostics.Process.GetProcessesByName("起動元アプリ名");
foreach (System.Diagnostics.Process hProcess in hProcesses)
{
if (!hProcess.CloseMainWindow())
{
hProcess.Kill();
}
}
----------------------------------------------------------------------
これは10秒で消えるとかアプリの仕様によって違うのですが、今回は.Netアプリの起動時間を誤魔化すのが趣旨ですので、このようにしました。このやり方の注意はもちろん起動元アプリ名がかなりユニークじゃないと危険ですね。ご注意をW 本当なら開いた側が自分のPIDを.Netアプリを開く時に引数として渡して、そのPIDを使って閉じるのが安全ですね。
以上、こんな感じでそれなりに動いています。
やはり体感っていうかイメージがかなり違いますね。
「もたぁ~~~」&「なにやってんだ?」ってイメージから「なんかやってるけど遅いなぁ」って感じでMSオフィスとかVSとかを開いているなれた重さって感じです。(← 良いかどうかは別としてW)
そもそも.Netアプリケーションは遅いってイメージを私も持ってましたけど、起動後は気になるほどの遅さじゃないですよね。まあ、たしかにネイティブコンパイルされたアプリよりは若干遅いですが。よほど高速な動作をもとめられるアプリじゃないかぎり問題ないのではないと最近感じてます。
ただし、起動は遅い。これは確かにそうだ。そう感じる。 と常々思っていたのですが、今回今更ながらまともに調べてみました。
それでわかったことは、今まで私はVS等で出力される中間コードであるMSIL(Microsoft Intermediate Language)をユーザーのPCでJIT(Just-In-Time)コンパイラでネイティブコンパイルするのが遅いものだと思ってました。でも実はよほど大きなプログラムじゃないかぎりJITは思ってたより遅くないですね。(もちろん早くは無いけどね)
それよりも.NetFrameWork自体の起動がやたら長く感じるのが原因ってことが良くわかりました。(← 間違えてたらごめん) しかも遅いってのもさることながら.NetFrameWorkの起動中になにも表示されないから、なにしてるのか気になるし、クリック失敗したかな?と思って重複起動してさらに遅くなるし、、、ってのでイライラしちゃうんですよね。なんかイメージとして「もたぁ~~~」っとした起動に感じるんです。
ユーザーのPCでJITする時間はインストール時とかにngen使ってプレコンパイルしてイメージ化しておけば、ある程度緩和できるはずですが、管理者権限が必要だとか、効果は微妙でプログラムの内容によっては効果がなかったり、場合によっては動作効率悪くなったり、その上結局.NetFrameWorkの起動時間は必要ってので、あまり期待できないですね。他の人のそういう意見も聞きますし。
ってことで、んじゃどうしようかと考えていたのですが、とりあえず、ぱっと思いつくのは3つでした。
1、次期Windowsを待つ。.NetFrameWork対応とのことなので、この辺も改善されると予想する。希望する。なれ!
2、PCの起動時(スタートアップ)に非表示の.Netアプリケーションを起動して常駐する。これによって.NetFrameWorkは既に起動されているのでその後の.Netアプリケーションの起動時間が少なくなるはず。
3、アンマネージドでネイティブコンパイル済みのスプラッシュ・スクリーン表示して.Netアプリケーションを起動するプログラムを作成する。これにより体感速度の向上と無意味な重複起動のリスクを削減。
ってな感じです。
とりあえず1については今はどうしようもないし、直ぐに全員が移行するわけではないので、却下。しょうがない。
2と3については改善される可能性はあるが、どっちにするかはそのアプリケーションの内容次第と言ったところでしょうか。
3は根本的な解決にならないので開発者の目の届く範囲で、且つ.NetFrameWorkを理解しているユーザーの場合には2が有効ではないかと思います。逆に2は不特定多数の一般ユーザーが対象だとユーザーは気持ち悪いと思うかもしれないし、無駄なリソースを取られるのでうざいと思われても仕方が無いかも、、、PCの起動が遅くなるわけですから。
3は根本的な解決とは程遠いですが、場合によって体感がかなり違うので不特定多数の一般ユーザーには優しいと思われます。(解決じゃなくて誤魔化し?) まあ、でもスプラッシュスクリーン自体が好まれているわけではないので、これも使いどころですね~。
ということで早速3を試して見ました。
以下、私がやった概要
####################################################################
初めにアンマネージドC++でスプラッシュ・スクリーン表示して.Netアプリケーションを起動するプログラムを作成します。
(私はC++が得意じゃないので、作り方の詳細は検索で調べてくださいね。)
私の場合はわざわざVC++6でMFCアプリケーションウィザードでSDIでMFCスタティックライブラリを使用するアプリケーションをウィザード通りに作成して、「プロジェクト>プロジェクトへ追加>コンポーネントおよびコントロール」からVisual C++ Componentsの中にあるスプラッシュスクリーンを追加して、あとはいらないコードをチェックしながら削除していきました。
これでスプラッシュ・スクリーンを追加されたので、あとは.Netアプリケーションを起動するだけです。ちなみに他アプリの起動はInitInstance()内に
[ShellExecute(NULL, "open", "appname.exe", NULL, NULL, SW_SHOW);]
こんな感じで追加しました。これで一応完成。
尚、私は通常VS2005で開発してるので、このプロジェクトをVC2005に取り込みました。
そしたらなんと完成物のサイズがなんと2倍に、、、、なぜだ、、、MFCが違うのか???
ちなみに私の場合ですとこのアプリが400kあります。これっぽっちのアプリに400kはちょっと凹みました。とはいっても5,6割はbitmapとiconの重さですけどね。
あとはスプラッシュ・スクリーンがどのタイミングで消えるのかっていうことですが、
私の場合には開く方側のアプリでは閉じないで、.Netアプリが起動したら.Netアプリ側から起動元のアプリを閉じるようにしました。
こんな感じ (C#)
----------------------------------------------------------------------
System.Diagnostics.Process[] hProcesses = System.Diagnostics.Process.GetProcessesByName("起動元アプリ名");
foreach (System.Diagnostics.Process hProcess in hProcesses)
{
if (!hProcess.CloseMainWindow())
{
hProcess.Kill();
}
}
----------------------------------------------------------------------
これは10秒で消えるとかアプリの仕様によって違うのですが、今回は.Netアプリの起動時間を誤魔化すのが趣旨ですので、このようにしました。このやり方の注意はもちろん起動元アプリ名がかなりユニークじゃないと危険ですね。ご注意をW 本当なら開いた側が自分のPIDを.Netアプリを開く時に引数として渡して、そのPIDを使って閉じるのが安全ですね。
以上、こんな感じでそれなりに動いています。
やはり体感っていうかイメージがかなり違いますね。
「もたぁ~~~」&「なにやってんだ?」ってイメージから「なんかやってるけど遅いなぁ」って感じでMSオフィスとかVSとかを開いているなれた重さって感じです。(← 良いかどうかは別としてW)
同じテーマの記事
- C#からIndex Serviceを使… 09月15日
- C#からIMEを使って逆検索でかな変換… 09月15日
- C#でWSSE認証クライアント 06月15日
- 最新の記事一覧 >>
PR
1 ■アダルトな時間には優雅な楽しみがあるのです
アダルト