我有以下点击事件。
protected void btnUpdate_Click(object sender, EventArgs e) {
foreach (GridViewRow gvr in gvEditBulletins.Rows) {
RadEditor re = (RadEditor)gvr.FindControl("reBulletin");
DropDownList ddl = (DropDownList)gvr.FindControl("ddlPosition");
// Business logic
}
}
我是否因为每次迭代都声明RadEditor和DropDownList的实例而遭受性能损失,或者编译器是否足够聪明以便知道重用实例?
答案 0 :(得分:3)
它没有创建新实例(除非在创建它们的控件上有自定义显式强制转换操作符)。 Find会找到一个exising对象并为你投射。
答案 1 :(得分:2)
首先,甚至担心这是微观优化;在研究应用程序的性能之前,您不必担心它,并且分析表明此方法和此循环是瓶颈。其次,是的,编译器将重用局部变量re
和ddl
的相同实例。
这是一个非常简单的例子:
class Program {
static void Main(string[] args) {
string[] strings = new [] { "hello", "world" };
foreach (string s in strings) {
int i = s.Length;
}
return;
}
}
这是IL:
.method private hidebysig static void Main(string[] args) cil managed {
.entrypoint
.maxstack 3
.locals init (
[0] string[] strings,
[1] string s,
---> [2] int32 i,
[3] string[] CS$0$0000,
[4] string[] CS$6$0001,
[5] int32 CS$7$0002,
[6] bool CS$4$0003)
L_0000: nop
L_0001: ldc.i4.2
L_0002: newarr string
L_0007: stloc.3
L_0008: ldloc.3
L_0009: ldc.i4.0
L_000a: ldstr "hello"
L_000f: stelem.ref
L_0010: ldloc.3
L_0011: ldc.i4.1
L_0012: ldstr "world"
L_0017: stelem.ref
L_0018: ldloc.3
L_0019: stloc.0
L_001a: nop
L_001b: ldloc.0
L_001c: stloc.s CS$6$0001
L_001e: ldc.i4.0
L_001f: stloc.s CS$7$0002
L_0021: br.s L_0038
L_0023: ldloc.s CS$6$0001
L_0025: ldloc.s CS$7$0002
L_0027: ldelem.ref
L_0028: stloc.1
L_0029: nop
L_002a: ldloc.1
--->L_002b: callvirt instance int32 [mscorlib]System.String::get_Length()
--->L_0030: stloc.2
L_0031: nop
L_0032: ldloc.s CS$7$0002
L_0034: ldc.i4.1
L_0035: add
L_0036: stloc.s CS$7$0002
L_0038: ldloc.s CS$7$0002
L_003a: ldloc.s CS$6$0001
L_003c: ldlen
L_003d: conv.i4
L_003e: clt
L_0040: stloc.s CS$4$0003
L_0042: ldloc.s CS$4$0003
L_0044: brtrue.s L_0023
L_0046: br.s L_0048
L_0048: ret
}
请注意,在locals部分中,变量i
被声明为占用堆栈上的第二个位置,这是get_Length
的结果在循环的每次迭代中重复存储的位置。 (我已在边距中突出显示--->
s的相关行。)
答案 2 :(得分:0)
由于页面上已经存在这些控件,因此不应该产生任何性能损失。否则你怎么能找到它们?
答案 3 :(得分:0)
性能如何?你能每秒点击1000次按钮吗?如果是这样,可能成为一个问题。