В чем преимущество использования out/ref по сравнению с возвратом?C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 В чем преимущество использования out/ref по сравнению с возвратом?

Сообщение Anonymous »

Я делаю игру с использованием платформы XNA, поэтому использую множество функций, работающих с векторами. (особенно Vector2 (64-битная структура)). Что меня беспокоит, так это то, что большинство методов определяются с параметрами ref и out. Вот пример:

Код: Выделить всё

void Min(ref Vector2 value1, ref Vector2 value2, out Vector2 result)
что мне тоже кажется немного странным. Есть еще один Мин, который более очевиден

Код: Выделить всё

public static Vector2 Min(Vector2 value1, Vector2 value2);
По сути, почти все функции имеют перегрузки с ref и out. Аналогично и другие API.

В чем преимущество такого дизайна? XNA оптимизирован по производительности, может ли это быть результатом? Скажем, Quaternion требует 128b, где передача по ссылке меньше.

РЕДАКТИРОВАТЬ:

Вот тестовый код:

Код: Выделить всё

public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;

private Vector2 vec1 = new Vector2(1, 2);
private Vector2 vec2 = new Vector2(2, 3);
private Vector2 min;
private string timeRefOut1;
private string timeRefOut2;
private SpriteFont font;

public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";

refOut1();
refOut2();
}

private Vector2 refOut1()
{
Vector2 min = Vector2.Min(vec1, vec2);
return min;
}

private Vector2 refOut2()
{
Vector2.Min(ref vec1, ref vec2, out min);
return min;
}

protected override void Initialize()
{
const int len = 100000000;
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
for (int i = 0; i < len; i++)
{
refOut1();
}
stopWatch.Stop();

timeRefOut1 = stopWatch.ElapsedMilliseconds.ToString();

stopWatch.Reset();
stopWatch.Start();
for (int i = 0; i < len; i++)
{
refOut2();
}
stopWatch.Stop();

timeRefOut2 = stopWatch.ElapsedMilliseconds.ToString();

base.Initialize();
}

protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
font = Content.Load("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)
{
GraphicsDevice.Clear(Color.CornflowerBlue);

spriteBatch.Begin();
spriteBatch.DrawString(font, timeRefOut1, new Vector2(200, 200), Color.White);
spriteBatch.DrawString(font, timeRefOut2, new Vector2(200, 300), Color.White);
spriteBatch.End();

// TODO: Add your drawing code here

base.Draw(gameTime);
}
}
Результаты:
  • refOut1 2200
  • refOut2 1400
Win 7 64 бит, .Net 4. XNA 4.0

Также IL-код

Код: Выделить всё

.method public hidebysig static void  Min(valuetype Microsoft.Xna.Framework.Vector2& value1,
valuetype Microsoft.Xna.Framework.Vector2& value2,
[out] valuetype Microsoft.Xna.Framework.Vector2& result) cil managed
{
// Code size       69 (0x45)
.maxstack  3
IL_0000:  ldarg.2
IL_0001:  ldarg.0
IL_0002:  ldfld      float32 Microsoft.Xna.Framework.Vector2::X
IL_0007:  ldarg.1
IL_0008:  ldfld      float32 Microsoft.Xna.Framework.Vector2::X
IL_000d:  blt.s      IL_0017
IL_000f:  ldarg.1
IL_0010:  ldfld      float32 Microsoft.Xna.Framework.Vector2::X
IL_0015:  br.s       IL_001d
IL_0017:  ldarg.0
IL_0018:  ldfld      float32 Microsoft.Xna.Framework.Vector2::X
IL_001d:  stfld      float32 Microsoft.Xna.Framework.Vector2::X
IL_0022:  ldarg.2
IL_0023:  ldarg.0
IL_0024:  ldfld      float32 Microsoft.Xna.Framework.Vector2::Y
IL_0029:  ldarg.1
IL_002a:  ldfld      float32 Microsoft.Xna.Framework.Vector2::Y
IL_002f:  blt.s      IL_0039
IL_0031:  ldarg.1
IL_0032:  ldfld      float32 Microsoft.Xna.Framework.Vector2::Y
IL_0037:  br.s       IL_003f
IL_0039:  ldarg.0
IL_003a:  ldfld      float32 Microsoft.Xna.Framework.Vector2::Y
IL_003f:  stfld      float32 Microsoft.Xna.Framework.Vector2::Y
IL_0044:  ret
} // end of method Vector2::Min
и

Код: Выделить всё

.method public hidebysig static valuetype Microsoft.Xna.Framework.Vector2
Min(valuetype Microsoft.Xna.Framework.Vector2 value1,
valuetype Microsoft.Xna.Framework.Vector2 value2) cil managed
{
// Code size       80 (0x50)
.maxstack  3
.locals init (valuetype Microsoft.Xna.Framework.Vector2 V_0)
IL_0000:  ldloca.s   V_0
IL_0002:  ldarga.s   value1
IL_0004:  ldfld      float32 Microsoft.Xna.Framework.Vector2::X
IL_0009:  ldarga.s   value2
IL_000b:  ldfld      float32 Microsoft.Xna.Framework.Vector2::X
IL_0010:  blt.s      IL_001b
IL_0012:  ldarga.s   value2
IL_0014:  ldfld      float32 Microsoft.Xna.Framework.Vector2::X
IL_0019:  br.s       IL_0022
IL_001b:  ldarga.s   value1
IL_001d:  ldfld      float32 Microsoft.Xna.Framework.Vector2::X
IL_0022:  stfld      float32 Microsoft.Xna.Framework.Vector2::X
IL_0027:  ldloca.s   V_0
IL_0029:  ldarga.s   value1
IL_002b:  ldfld      float32 Microsoft.Xna.Framework.Vector2::Y
IL_0030:  ldarga.s   value2
IL_0032:  ldfld      float32 Microsoft.Xna.Framework.Vector2::Y
IL_0037:  blt.s      IL_0042
IL_0039:  ldarga.s   value2
IL_003b:  ldfld      float32 Microsoft.Xna.Framework.Vector2::Y
IL_0040:  br.s       IL_0049
IL_0042:  ldarga.s   value1
IL_0044:  ldfld      float32 Microsoft.Xna.Framework.Vector2::Y
IL_0049:  stfld      float32 Microsoft.Xna.Framework.Vector2::Y
IL_004e:  ldloc.0
IL_004f:  ret
} // end of method Vector2::Min
Похоже, накладные расходы вызваны временным вектором. Также я пробовал устройство WP 7.5 с частотой 1 ГГц:
  • 1979
  • 1677
Количество тактов при на порядок меньшем количестве итераций.

Подробнее здесь: https://stackoverflow.com/questions/105 ... -returning
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»