プロファイル(for vs foreach)
C#を使用しているとC言語だとforで記述している部分を(foreach)でも表記できる場合がおおいのですが、どっちがはやいのかな?
namespace Profiler2 { public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; private SpriteFont font; private TimeSpan timeData; const int V_MAX = 100; private Vector2[] vTest = new Vector2[V_MAX]; 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"); for (int i = 0; i < V_MAX; i++) vTest[i] = new Vector2(); } 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; for (int i = 0; i < 1000000; i++) forTest2(); 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 forTest() { float f; for (int i = 0; i < V_MAX; i++) f = vTest[i].X; } } }
■forに関して
private void forTest() { float f; for (int i = 0; i < V_MAX; i++) f = vTest[i].X; }
.method private hidebysig instance void forTest() cil managed { // コード サイズ 32 (0x20) .maxstack 2 .locals init ([0] int32 i) IL_0000: ldc.i4.0 IL_0001: stloc.0 IL_0002: br.s IL_001a IL_0004: ldarg.0 IL_0005: ldfld valuetype [Microsoft.Xna.Framework]Microsoft.Xna.Framework.Vector2[] Profiler2.Game1::vTest IL_000a: ldloc.0 IL_000b: ldelema [Microsoft.Xna.Framework]Microsoft.Xna.Framework.Vector2 IL_0010: ldfld float32 [Microsoft.Xna.Framework]Microsoft.Xna.Framework.Vector2::X IL_0015: pop IL_0016: ldloc.0 IL_0017: ldc.i4.1 IL_0018: add IL_0019: stloc.0 IL_001a: ldloc.0 IL_001b: ldc.i4.s 100 IL_001d: blt.s IL_0004 IL_001f: ret } // end of method Game1::forTest
■foreachに関して
private void forTest() { float f; foreach (Vector2 v in vTest) f = v.X; }
.method private hidebysig instance void forTest() cil managed { // コード サイズ 35 (0x23) .maxstack 2 .locals init ([0] valuetype [Microsoft.Xna.Framework]Microsoft.Xna.Framework.Vector2 v, [1] valuetype [Microsoft.Xna.Framework]Microsoft.Xna.Framework.Vector2[] CS$6$0000, [2] int32 CS$7$0001) IL_0000: ldarg.0 IL_0001: ldfld valuetype [Microsoft.Xna.Framework]Microsoft.Xna.Framework.Vector2[] Profiler2.Game1::vTest IL_0006: stloc.1 IL_0007: ldc.i4.0 IL_0008: stloc.2 IL_0009: br.s IL_001c IL_000b: ldloc.1 IL_000c: ldloc.2 IL_000d: ldelema [Microsoft.Xna.Framework]Microsoft.Xna.Framework.Vector2 IL_0012: ldobj [Microsoft.Xna.Framework]Microsoft.Xna.Framework.Vector2 IL_0017: stloc.0 IL_0018: ldloc.2 IL_0019: ldc.i4.1 IL_001a: add IL_001b: stloc.2 IL_001c: ldloc.2 IL_001d: ldloc.1 IL_001e: ldlen IL_001f: conv.i4 IL_0020: blt.s IL_000b IL_0022: ret } // end of method Game1::forTest
■比較
・forの場合
453.128ms(debug)
93.75ms(Release)
・foreachの場合
562.5ms(debug)
78.125ms(Release)
デバッグだと for の方が早かったのですが、Releaseだと foreach の方が早い結果が得られました。
なるべく foreach にした方がループの部分はいいみたい。