アクセス数 累計:000,123,257 昨日:000,000,095 本日:000,000,022
|
|
|
|
【Amazon ランキング:ゲーム - Wii U】
|
.NET アプリケーションを開発していると、WPF(Windows Presentation Foundation)という言葉をよく耳にします。WPF には様々なすぐれた機能がありますが、その中で自分が一番注目しているのはグラフィック描画の高速化です。 WPF が Direct3D を使用しているので今まで GDI でゴリゴリやっていた処理がどれだけ早くなったかとても興味あります。
フリーソフトの J.S Draw では GDI+ を駆使して高速な描画を実現していますが、時代の流れは WPF へと向かいつつあります。そこで GDI と WPF の描画性能を比較してどれぐらい高速になったかを計測してみることにしました。
|
テスト環境 |
CPU |
Intel Core i7 940 (2.93GHz 4コア) |
メモリー |
DDR3-1600 C9 6GB(2GB×3) |
GPU |
ATI Radeon HD 5700 (860MHz)
DDR5 1024MB (1200MHz) |
Direct 2D バージョン |
8.0.1.01.1030 |
Direct 3D バージョン |
8.14.10.0753 |
.NET Framework |
4.0 |
|
GDI |
プログラムは単純です。For 文で矩形を 25,000 個描画した時間を計測します。
GDI 描画の高速化のためにダブルバッファの手法を用いています。
|
C#[GDI.Form1.cs] |
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace GDI
{
public partial class Form1 : Form
{
private Bitmap _screenBmp = null;
public Form1()
{
InitializeComponent();
// イメージ作成
_screenBmp = new Bitmap(1000, 1000,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
using (Graphics g = Graphics.FromImage(_screenBmp))
g.Clear(this.BackColor);
}
private void button1_Click(object sender, EventArgs e)
{
DateTime stTime = DateTime.Now;
using (Graphics g = Graphics.FromImage(_screenBmp))
{
g.Clear(this.BackColor);
for (int x = 0; x < 1000; x += 2)
{
for (int y = 0; y < 1000; y += 2)
{
this.DrawRect(g, x, y);
}
}
}
this.RefleshScreen();
TimeSpan span = DateTime.Now - stTime;
MessageBox.Show(string.Format("描画時間:{0}.{1}秒",
span.Seconds, span.Milliseconds),
"GDI 矩形描画", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
/// <summary>
/// 矩形を描画する
/// </summary>
/// <param name="pt"></param>
private void DrawRect(Graphics g, float x, float y)
{
RectangleF rect = new RectangleF(x, y, 100F, 100F);
Brush brush = new SolidBrush(Color.White);
Pen pen = new Pen(Color.Black, 1);
g.FillRectangle(brush, rect);
g.DrawRectangle(pen, rect.X,rect.Y,rect.Width,rect.Height);
}
/// <summary>
/// 描画処理
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
if (_screenBmp != null)
{
e.Graphics.DrawImage(_screenBmp, 0, 25);
}
else
{
base.OnPaint(e);
}
}
/// <summary>
/// 高速化
/// </summary>
/// <param name="e"></param>
protected override void OnPaintBackground(PaintEventArgs e)
{
// 高速化のためバックグラウンドは描画しない。
//base.OnPaintBackground(e);
e.Graphics.Clear(this.BackColor);
return;
}
/// <summary>
/// スクリーンリフレッシュ
/// </summary>
protected void RefleshScreen()
{
this.CreateGraphics().DrawImage(_screenBmp, 0, 25);
}
}
}
|
|
|
WPF |
基本的なロジックは GDI版 と同じですが、矩形の描画に Windows.Shapse.Rectange オブジェクトを使用しています。
|
C#[WPF.MainWindow.xaml.cs] |
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WPF
{
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
DateTime stTime = DateTime.Now;
//this.canvas1.BeginInit();
for (int x = 0; x < 1000; x += 2)
{
for (int y = 0; y < 1000; y += 2)
{
this.DrawRect(x, y);
}
}
//this.canvas1.EndInit();
TimeSpan span = DateTime.Now - stTime;
MessageBox.Show(string.Format("描画時間:{0}.{1}秒",
span.Seconds, span.Milliseconds),
"WPF 矩形描画", MessageBoxButton.OK, MessageBoxImage.Information);
}
/// <summary>
/// 矩形を描画する
/// </summary>
/// <param name="pt"></param>
private void DrawRect(double x, double y)
{
Rectangle rect = new Rectangle();
rect.Width = 100;
rect.Height = 100;
rect.Stroke = new SolidColorBrush(Colors.Black);
rect.StrokeThickness = 1.0F;
rect.Fill = new SolidColorBrush(Colors.White);
Matrix rectsMatrix = (rect.RenderTransform as MatrixTransform).Matrix;
rectsMatrix.Translate(x, y);
rect.RenderTransform = new MatrixTransform(rectsMatrix);
this.canvas1.Children.Add(rect);
}
}
}
|
|
|
計測結果① |
|
一見 WPF の方が早いように思われますが、この結果にだまされてはいけません。
GDI の方はメッセージボックスの表示と同時に画面が描画されますが、WPF の方はメッセージが表示されてだいぶ遅れて画面が描画されます。そこで処理を開始して画面描画が完了するまでの時間を表にまとめました。
|
描画方法 |
メッセージ表示時間 |
画面描画完了時間 |
GDI |
9.750 秒 |
約 10 秒 |
WPF |
7.264 秒 |
約 42 秒 |
※画面描画完了時間はストップウォッチで計測しました。
|
この結果から矩形のような単純な図形の描画では GDI の圧勝ということになりました。今回のGDI プログラムではダブルバッファを用いて高速化を行っている点も GDI が早かった要因かもしれません。
|
|
計測結果② |
|
もうひとつ GPU と WPF で CPU 使用率を計測してみました。WPF では描画処理を GPU で行っているらしいですが....
2D の描画ではメインCPUを使っているみたいですね。WPF の新の力はマルチメディア再生や 3D描画でないと発揮されないのかもしれません。
|
|
※このページで紹介しているサンプルコードについて管理者は動作保障をいたしません※
※サンプルコードを使用する場合は、自己責任でお願いします※
|
【楽天 ランキング:パソコン・周辺機器 - ノートパソコン】
|
|
|
|
このサイトはフリーソフトのMerge HTMLで作成されています。
このサイトはリンクフリーです。
|
ページの先頭に戻る |
Copyright© 2010-2015 Jun.Shiozaki All rights reserved. |
|
|
|