不更有效地在经常调用的方法中设置新的临时变量吗? (> 1000x s)
这是一个当前的例子。我指定了3个新的整数值,而不是将这些值直接传递给另一个方法。
// What I'm currently doing
public virtual byte GetByte(Vector3 worldPos) {
worldPos -= transform.position;
int x = Mathf.FloorToInt(worldPos.x);
int y = Mathf.FloorToInt(worldPos.y);
int z = Mathf.FloorToInt(worldPos.z);
return GetByte(x, y, z);
}
但直接传递这些值会更有效,而不是分配3个新变量吗?
// would this be more efficient?
public virtual byte GetByte(Vector3 worldPos) {
worldPos -= transform.position;
return GetByte(
Mathf.FloorToInt(worldPos.x),
Mathf.FloorToInt(worldPos.y),
Mathf.FloorToInt(worldPos.z));
}
答案 0 :(得分:5)
没有区别。局部变量被添加到堆栈中。并且用作函数参数的值也会添加到堆栈中。因此,在这两种情况下,都会向堆栈添加相同的内容。
所以只要使用你认为更具可读性的东西。
答案 1 :(得分:2)
它们会导致生成不同的IL。
当前(使用int x = Mathf.FloorToInt(worldPos.x); ...):
.method public hidebysig newslot virtual instance uint8 GetByte1 (
valuetype ConsoleApplication5.Vector3 worldPos
) cil managed
{
.locals init (
[0] int32 x,
[1] int32 y,
[2] int32 z
)
IL_0000: ldarga.s worldPos
IL_0002: ldfld int32 ConsoleApplication5.Vector3::x
IL_0007: call int32 ConsoleApplication5.Mathf::FloorToInt(int32)
IL_000c: stloc.0
IL_000d: ldarga.s worldPos
IL_000f: ldfld int32 ConsoleApplication5.Vector3::y
IL_0014: call int32 ConsoleApplication5.Mathf::FloorToInt(int32)
IL_0019: stloc.1
IL_001a: ldarga.s worldPos
IL_001c: ldfld int32 ConsoleApplication5.Vector3::z
IL_0021: call int32 ConsoleApplication5.Mathf::FloorToInt(int32)
IL_0026: stloc.2
IL_0027: ldarg.0
IL_0028: ldloc.0
IL_0029: ldloc.1
IL_002a: ldloc.2
IL_002b: call instance uint8 ConsoleApplication5.X::GetByte(int32, int32, int32)
IL_0030: ret
}
替代:
.method public hidebysig newslot virtual instance uint8 GetByte2 (
valuetype ConsoleApplication5.Vector3 worldPos
) cil managed
{
IL_0000: ldarg.0
IL_0001: ldarga.s worldPos
IL_0003: ldfld int32 ConsoleApplication5.Vector3::x
IL_0008: call int32 ConsoleApplication5.Mathf::FloorToInt(int32)
IL_000d: ldarga.s worldPos
IL_000f: ldfld int32 ConsoleApplication5.Vector3::y
IL_0014: call int32 ConsoleApplication5.Mathf::FloorToInt(int32)
IL_0019: ldarga.s worldPos
IL_001b: ldfld int32 ConsoleApplication5.Vector3::z
IL_0020: call int32 ConsoleApplication5.Mathf::FloorToInt(int32)
IL_0025: call instance uint8 ConsoleApplication5.X::GetByte(int32, int32, int32)
IL_002a: ret
}
理论上,替代可以更高效,因为它不会产生从局部变量存储和检索int值的成本,因此执行该方法所需的指令较少。但是,代码MSIL在运行时仍然会被JIT,并且可能会根据它的优化方式而结束。
我会坚持使用当前版本,因为它可以使调试更容易,因为您可以通过检查变量来查看FloorToInt
调用的结果。
唯一可以确定的方法是对代码进行基准测试,虽然这是一个相当无意义的优化问题,但可能有更好的方法来加速您的应用程序!