すらすらプログラマーへのお問い合わせ
すらすらのブログ
アクセス数  累計:000,099,173  昨日:000,000,137  本日:000,000,073
Loading
やってみよう!
.NET プログラミング
プロパティグリッド
印刷
リストボックス
スレッド
リストビュー
インストーラー
やってみよう!

できるVisual Studio 2015 Windows /Android/iOS アプリ対応

独習C# 第3版

VisualBasic2013パーフェクトマスター (Perfect Master SERIES)

プログラミング.NET Framework 第4版 (Microsoft Press)

VisualBasic2013逆引き大全555の極意

猫でもわかるWindowsプログラミング 第4版 (猫でもわかるプログラミング)

VisualC#2013逆引き大全555の極意

GDI vs WPF ① 最終更新:2010/12/05
【Amazon ランキング:本 - ゲーム攻略・ゲームブック】

.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);
        }
    }
}
計測結果①
GDI WPF
一見 WPF の方が早いように思われますが、この結果にだまされてはいけません。
GDI の方はメッセージボックスの表示と同時に画面が描画されますが、WPF の方はメッセージが表示されてだいぶ遅れて画面が描画されます。そこで処理を開始して画面描画が完了するまでの時間を表にまとめました。
描画方法 メッセージ表示時間 画面描画完了時間
GDI 9.750 秒 約 10 秒
WPF 7.264 秒 約 42 秒
※画面描画完了時間はストップウォッチで計測しました。
この結果から矩形のような単純な図形の描画では GDI の圧勝ということになりました。今回のGDI プログラムではダブルバッファを用いて高速化を行っている点も GDI が早かった要因かもしれません。
計測結果②
GDI WPF
もうひとつ GPU と WPF で CPU 使用率を計測してみました。WPF では描画処理を GPU で行っているらしいですが....
2D の描画ではメインCPUを使っているみたいですね。WPF の新の力はマルチメディア再生や 3D描画でないと発揮されないのかもしれません。
※このページで紹介しているサンプルコードについて管理者は動作保障をいたしません※
※サンプルコードを使用する場合は、自己責任でお願いします※

【楽天 ランキング:パソコン・周辺機器 - ノートパソコン】




このサイトはフリーソフトのMerge HTMLで作成されています。
このサイトはリンクフリーです。

ページの先頭に戻る Copyright© 2010-2015 Jun.Shiozaki All rights reserved.