【问题标题】:Can value types be implemented by inlining?值类型可以通过内联来实现吗?
【发布时间】:2011-09-11 07:32:22
【问题描述】:

当我第一次看到 C# 中的值类型时,我想到的第一件事是“哇,多么棒的优化”,第二件事是,“我们真的需要一种新的语言结构吗?我们不能用而是注释?”。

我们的想法是,给定一个类,我们将像往常一样使用它

class A {int i;}
class B {
    A m_a;
    int F(A a) {m_a = a;}
}

一时兴起,我们将A改为

[ValueType]
class A {int i;int j;}

并且编译器会自动将B类转换为

class B {
#region A
    int A_i;
    int A_j;
#endregion
int F(/*A param*/int i,int j) {
#region A_assign
    A_i = i;
    A_j = j;
#endregion
}

请记住,如果编译器不希望优化某些实例 - 它不必这样做。无论哪种方式都可以。

模板可能会出现问题,

int f<T>() {
    T t; // how much stack should I allocate
}

但我不确定它是否比目前的情况更糟。我实际上不确定现在会发生什么(f&lt;struct_of_100_bytes&gt;f&lt;int&gt; 的功能不同吗?)。

【问题讨论】:

    标签: c# jvm language-design value-type vm-implementation


    【解决方案1】:

    现在想象一下继承。或数组。或论据。或泛型。或者实现一个接口。或分配给对象/动态。

    请记住,运行时支持多个编译器。

    拥有一个特定的关键字(结构)而不是一个属性并不是一个很大的变化(实际上,在 CLI 方面,所有东西都称为一个类),但总体情况比您的示例复杂得多。

    基本上, struct 几乎可以完成您提到的所有事情,并且适用于列出的所有场景。由于它通常(对于本地人)使用堆栈,它的行为已经很像你描述的。

    关于“分离功能”的问题;首先,泛型不是“模板”(它是运行时与编译时)。但是泛型每个值类型都有一个 JIT,每个引用类型有一个 JIT(因为确实:堆栈布局发生了变化。

    【讨论】:

    • 您总是可以退回到常规对象(您制作了一个非常混乱的对象?没有适合您的内联)。而且我并没有真正看到(如不理解,而不是不同意)继承(C++ 执行值类型继承)、数组、参数、泛型或实现接口如何干扰内联,这似乎是可能的在所有三种情况下。你能扩展一下吗?也许举个例子会有所帮助。
    • @Elazar 在将接口作为参数传递的情况下,例如,它根本没有意义——调用者不知道该做什么。但在一般情况下,这与结构的工作方式非常相似。不知道这里有什么意义
    • 哦,我明白了。将实现接口的结构作为函数参数传递时。 (在那种情况下,我确实打算回退。)谢谢。还有一个问题,听说VM本身就支持值类型,单靠编译器配合好像也可以。
    • @Elazar 是的,但这会影响互操作 - 因为每个编译器可能会以不同的方式执行它。我喜欢让 JIT 在这里定义规则。另外 - 封装和可访问性是这里的一个大问题。
    猜你喜欢
    • 1970-01-01
    • 2022-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    • 2017-11-01
    • 2015-05-16
    相关资源
    最近更新 更多