将类中的方法替换为扩展方法更有效吗?

时间:2012-09-05 17:42:34

标签: c# performance extension-methods

我使用this apreach递归查找目录中的所有文件,这非常快。

无论如何我将信息存储在struct的每个文件中:

struct Info 
{
    public bool IsDirectory;
    public string Path;
    public FILETIME ModifiedDate;
}

所以现在我正在尝试决定天气将辅助方法放在该结构中或其他地方以提高效率。

辅助方法是:

struct Info 
{
    public bool IsDirectory;
    public string Path;
    public FILETIME ModifiedDate;

    // Helper methods:
    public string GetFileName(){ /* implementation */ }
    public string GetFileSize(){ /* implementation */ }
    public string GetFileAtributes() { /* implementation */ }
    // etc many more helper methods
}

我在内存中保存了数千个文件,我不知道在Info中使用这些方法是否会影响性能。换句话说,最好删除这些方法并将它们作为扩展方法:

public static class ExtensionHelperMethods
{
    static public string GetFileName(this Info info){ /* implementation */ }
    static public string GetFileSize(this Info info){ /* implementation */ }
    static public string GetFileAtributes(this Info info) { /* implementation */ }
    // etc many more helper methods
}

所以我的问题是因为Info是一个实例结构,那么内部使用这些方法会导致更多的内存消耗?如果Info是一个实例结构,那么每个方法在内存中都有不同的地址吗?

我尝试了两种技术,但我似乎没有看到差异。也许我需要尝试更多文件。


修改

这是为了证明@Fabio Gouw是怀特:

// This program compares the size of object a and b
class Program
{
    static void Main(string[] args)
    {
        InfoA a = new InfoA();
        InfoB b = new InfoB();

        if (ToBytes(a).Length == ToBytes(b).Length)
        {
            Console.Write("Objects are the same size!!!");
        }

        Console.Read();
    }

    public static byte[] ToBytes(object objectToSerialize)
    {
        BinaryFormatter bf = new BinaryFormatter();
        MemoryStream memStr = new MemoryStream();

        try
        {
            bf.Serialize(memStr, objectToSerialize);
            memStr.Position = 0;

            var ret = memStr.ToArray();

            return ret;
        }
        finally
        {
            memStr.Close();
        }
    }

    [Serializable]
    struct InfoA
    {
        public bool IsDirectory;
        public string Path;
    }

    [Serializable]
    struct InfoB
    {
        public bool IsDirectory;
        public string Path;

        public string GetFileName()
        {
            return System.IO.Path.GetFileName(Path);
        }
    }
}

2 个答案:

答案 0 :(得分:5)

方法不会干扰对象大小,只会对字段进行干扰(方法是行为;字段是数据,这些是存储在内存中)。将它们放入Info类或作为扩展方法的决定只是一个设计问题。

此问题与您的问题类似:Memory usage when converting methods to static methods

答案 1 :(得分:0)

我倾向于将结构限制为对象形状而不是行为。类更倾向于行为。更大的潜在问题是如何传递类型,特别是在将类型作为方法参数传递时,观察装箱操作和堆栈/堆分配。

话虽这么说,类的扩展方法主要是调用本机静态方法的语法糖。编译器将扩​​展方法转换为对Extension方法的调用,因此静态方法和扩展方法之间不应存在运行时性能差异。

如果您稍后在底层类/结构中添加类似的方法并且发现在您期望使用扩展方法时使用本机方法,则扩展方法确实可以在脚中拍摄自己。此外,与可以与常规静态方法一起使用的完全限定名称或命名空间别名相比,扩展方法更难消除歧义。有关如何编译扩展方法的更多信息,请参阅http://www.thinqlinq.com/Post.aspx/Title/DLinq-Extension-Methods-Decomposed