流畅的接口是否会显著影响.NET应用程序的运行时性能?

流畅的接口是否会显著影响.NET应用程序的运行时性能?,.net,performance,garbage-collection,runtime,fluent-interface,.net,Performance,Garbage Collection,Runtime,Fluent Interface,我目前正忙于为现有技术实现一个流畅的界面,这将允许类似于以下代码片段的代码: using (var directory = Open.Directory(@"path\to\some\directory")) { using (var file = Open.File("foobar.html").In(directory)) { // ... } } 为了实现这样的结构,需要类来积累参数并将其传递给其他对象。例如,要在(…)构造中实现Open.File

我目前正忙于为现有技术实现一个流畅的界面,这将允许类似于以下代码片段的代码:

using (var directory = Open.Directory(@"path\to\some\directory"))
{
    using (var file = Open.File("foobar.html").In(directory))
    {
        // ...
    }
}
为了实现这样的结构,需要类来积累参数并将其传递给其他对象。例如,要在(…)构造中实现
Open.File(…)。需要两个类:

// handles 'Open.XXX':
public static class OpenPhrase
{
    // handles 'Open.File(XXX)':
    public static OpenFilePhrase File(string filename)
    {
        return new OpenFilePhrase(filename);
    }

    // handles 'Open.Directory(XXX)':
    public static DirectoryObject Directory(string path)
    {
        // ...
    }
}

// handles 'Open.File(XXX).XXX':
public class OpenFilePhrase
{
    internal OpenFilePhrase(string filename)
    {
        _filename = filename
    }

    // handles 'Open.File(XXX).In(XXX):
    public FileObject In(DirectoryObject directory)
    {
        // ...
    }

    private readonly string _filename;
}
也就是说,语句(如初始示例)的组成部分越多,需要创建的对象就越多,以便将参数传递给链中的后续对象,直到实际语句最终可以执行为止

问题: 我对一些观点感兴趣:使用上述技术实现的fluent接口是否会显著影响使用它的应用程序的运行时性能?关于运行时性能,我指的是速度和内存使用方面

请记住,可能需要为非常短的时间间隔创建大量临时的、保存参数的对象,我认为这可能会给垃圾收集器带来一定的压力


如果您认为存在显著的性能影响,您知道实现流畅接口的更好方法吗?

一般来说,生命周期非常短的对象正是GC最有效处理的对象,因为在下一个次要收集运行时,它们中的大多数都将死亡——并且在任何合适的GC实现上,次要收集的成本与活动对象的总大小成正比。因此,短期对象的成本非常低,它们的分配意味着只需向上移动一个指针,这非常快


所以我想说:可能没有显著的性能影响。

Thomas非常正确,分代GC正是针对这种短期对象的分配和收集而优化的。然而,像OCaml这样的函数式语言的GCs在这方面比.NET要优化得多,然而,在将多个参数应用于一个curried函数的等效情况下,它们仍然竭尽全力避免这种情况。具体地说,他们使用了一种称为大步语义的技术,编译器在编译时删除所有的中间对象,因此GC永远不会看到这些


在.NET上,值类型很可能让您自己解决这个问题。

@TrueWill:我想这肯定会影响性能。然而(或者至少在我上面给出的代码示例中),终结器不应该是必需的,因为所有这些寿命短、带有参数的“中间”对象都是非常轻量级的,除了将其参数传递给后续对象之外,实际上不做任何工作。我认为这样的类永远不需要终结器。@stakx:终结器很少需要。当实例对应于非内存的已分配资源时(内存由GC处理,GC擅长于此),它们就起作用了。这里,只有记忆。我完全同意终结器会影响性能。从本质上讲,一个可终结的对象至少会抵制一个次要的GC收集,也就是说,在该点上必须仍然被认为是活动的。