堆栈上的内存开销和A与B的堆是多少
A:
private string TestA() { string a = _builder.Build(); return a; }
B:
private string TestB() { return _builder.Build(); }
Marc Gravell.. 7
重新提出效率问题; 两者是相同的,在发布模式下将减少到相同的东西.无论哪种方式,string
都是引用类型,因此它string
本身总是在堆上.堆栈上唯一的东西就是引用string
- 几个字节(无论字符串长度).
"将所有局部变量放在堆栈上":不; 有两个例外:
捕获变量(匿名方法/ lambdas)
迭代器块(yield return
等)
在这两种情况下,幕后都有一个编译器生成的类:
int i = 1; Action action = delegate {i++;}; action(); Console.WriteLine(i);
类似于:
class Foo { public int i; // yes, a public field public void SomeMethod() {i++;} } ... Foo foo = new Foo(); foo.i = 1; Action action = foo.SomeMethod; action(); Console.WriteLine(foo.i);
因此i
是在一个对象上,因此在堆上.
迭代器块以类似的方式工作,但使用状态机.
重新提出效率问题; 两者是相同的,在发布模式下将减少到相同的东西.无论哪种方式,string
都是引用类型,因此它string
本身总是在堆上.堆栈上唯一的东西就是引用string
- 几个字节(无论字符串长度).
"将所有局部变量放在堆栈上":不; 有两个例外:
捕获变量(匿名方法/ lambdas)
迭代器块(yield return
等)
在这两种情况下,幕后都有一个编译器生成的类:
int i = 1; Action action = delegate {i++;}; action(); Console.WriteLine(i);
类似于:
class Foo { public int i; // yes, a public field public void SomeMethod() {i++;} } ... Foo foo = new Foo(); foo.i = 1; Action action = foo.SomeMethod; action(); Console.WriteLine(foo.i);
因此i
是在一个对象上,因此在堆上.
迭代器块以类似的方式工作,但使用状态机.