プロファイル(new)

C#でプログラムを書いていると、ついついあちこちでNEWをしてしまいます、でも本当によいのでしょうか?

namespace Profiler
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        private SpriteFont font;
        private TimeSpan timeData;
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            graphics.PreferredBackBufferWidth = 240;
            graphics.PreferredBackBufferHeight = 320;
            // Frame rate is 30 fps by default for Zune.
            TargetElapsedTime = TimeSpan.FromSeconds(1 / 30.0);
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            font = Content.Load<SpriteFont>("SpriteFont1");
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            DateTime timeNow = DateTime.Now;
            timeTest();
            timeData = DateTime.Now - timeNow;
            //----------------------------
            GraphicsDevice.Clear(Color.CornflowerBlue);
            spriteBatch.Begin();
            spriteBatch.DrawString(font, "time:" + timeData.TotalMilliseconds, new Vector2(50, 50), Color.White);
            spriteBatch.End();
            base.Draw(gameTime);
        }

        private void timeTest()
        {
            for (int i = 0; i < 1000000; i++)
            {
                int[] iData = new int[100];
                for (int j = 0; j < 100; j++)
                    iData[j] = j;
            }
        }
    }
}

Windows : 1000ms(Debug) : 218.75ms(Release)
Zune : 29000ms
XBOX360 : 2428ms(Debug) : 2156ms(Release)
上のプログラムは悪い例なので、なるべくNEWをしないように外に出してみましょう。

        private void timeTest()
        {
            int[] iData = new int[100];
            for (int i = 0; i < 1000000; i++)
            {
                for (int j = 0; j < 100; j++)
                    iData[j] = j;
            }
        }

Windows : 546.75ms(Debug) : 93.75ms(Release)
Zune : 17000ms
XBOX360 : 1602ms(Debug) : 1312ms(Release)
なるべくNEWをしないと確かにはやくなります、なら、いっそのことグローバル変数で定義してしまうと。

        private int[] iData = new int[100];
        private void timeTest()
        {
            for (int i = 0; i < 1000000; i++)
            {
                for (int j = 0; j < 100; j++)
                    iData[j] = j;
            }
        }

Windows : 609.375ms(Debug) : 93.75ms(Release)
Zune : 17000ms
XBOX360 : 1570ms(Debug) : 1276ms(Release)
少し早くなりました、ただ、iData[j]=jの部分でグローバル変数にアクセスしているのでこれをローカル変数に置き換えたら早くなるかもと思いテストしてみる。

        private int[] pData = new int[100];
        private void timeTest()
        {
            int[] iData = pData;
            for (int i = 0; i < 1000000; i++)
            {
                for (int j = 0; j < 100; j++)
                    iData[j] = j;
            }
        }

Windows : 468.75ms(Debug) : 93.75ms(Release)
Zune : 18000ms
XBOX360 : 1570ms(Debug) : 1277ms(Release)
Zuneで取得できる時間の精度は結構荒いですね・・・・
(今回WindowsはCoreDuo2.6のマシンで実験しています)