在.NET 4中,System.IO.Path对于Combine方法具有以下重载:

public static string Combine(params string[] paths)
public static string Combine(string path1, string path2)
public static string Combine(string path1, string path2, string path3)
public static string Combine(string path1, string path2, string path3, string path4)

.NET 4中添加了第一个,以支持任意数量的路径参数。第二个已经存在于较早的版本中,因此我想保留它是为了向后兼容。

但是我很好奇其他重载的用途。这些用例是否已被params的第一个方法签名所涵盖?

编辑:我现在认为答案是“因为并非所有语言都支持params(并且不方便地传递没有参数支持的数组)”。但是,stackoverflow hive 的人似乎强烈反对。因此,作为妥协,我不接受任何答案。

最佳答案

我会怀疑性能,因为您必须创建一个带参数的中间数组,再加上遍历该数组的开销等。可能存在一些内部情况,例如使用固定编号参数版本的情况。

更新

我现在进行了性能测试,以检查我的假设。首先,这是我应该做的事情-我打破了自己的表演口号:



我的假设并不完全正确,但也不完全错误。 4个固定参数版本比4个参数版本稍慢,但是3个和2个固定变量的性能要好得多。

当前接受的答案的性能测试工具存在很多问题,这些问题表明性能完全支持params版本-这是不正确的:

  • 它使用DateTime.Now进行计时-始终使用秒表作为DatTime进行微基准测试。Now仅精确到10ms-> 15ms之间。 There are endless articles on this
  • 该测试仅涉及4参数版本的情况-3和2参数版本呢?
  • 不考虑垃圾的产生和收集。一种方法在A-> B之间的直线上可能更快,但它可能还会产生大量垃圾,必须在某个阶段将其清除。这是递延的性能损失,但仍然对性能有影响,因此应考虑在内。
  • 确保参数具有实际值-合并单个字符路径是否现实?

  • 我得到以下性能结果,其中包括2、3和4个参数变体,可以看出2和3个变体的性能明显更好,而4个变体的性能稍差。固定数量的参数版本总体上更快,其中3个是最重要的问题(自.Net 1.1开始存在2个参数变体)。
    ***2 Args***
    params2:3018.44ms
    params2:3007.61ms
    params2:2988.52ms
    params2:2992.33ms
    params2:2995.89ms
    args2  :1724.83ms
    args2  :1723.97ms
    args2  :1727.76ms
    args2  :1720.42ms
    args2  :1718.24ms
    ***3 Args***
    params3:4168.37ms
    params3:4169.61ms
    params3:4165.63ms
    params3:4161.51ms
    params3:4153.61ms
    args3  :3476.96ms
    args3  :3483.40ms
    args3  :3482.49ms
    args3  :3595.15ms
    args3  :3561.11ms
    ***4 Args***
    params4:4992.71ms
    params4:4985.51ms
    params4:4995.63ms
    params4:5002.47ms
    params4:4993.99ms
    args4  :4993.02ms
    args4  :4992.93ms
    args4  :4991.07ms
    args4  :4993.04ms
    args4  :4995.14ms
    

    测试:
    public void MeasurePathPerformance()
    {
        const int TestIterations = 5;
        const string Root = "C:\\xxxxxxxxxx";
        string seg = new string('x', 10);
        string path = null;
    
        Action<string, Func<double>> test = (name, action) =>
        {
            for (int i = 0; i < TestIterations; i++)
            {
                Console.WriteLine("{0}:{1:F2}ms", name, action());
            }
        };
    
        Console.WriteLine("***2 Args***");
        Action p2 = () => path = Path.Combine(new[] { Root, seg });
        test("params2", () => TimeTest(p2));
        Action a2 = () => path = Path.Combine(Root, seg);
        test("args2  ", () => TimeTest(a2));
    
        Console.WriteLine("***3 Args***");
        Action p3 = () => path = Path.Combine(new[] { Root, seg, seg });
        test("params3", () => TimeTest(p3));
        Action a3 = () => path = Path.Combine(Root, seg, seg);
        test("args3  ", () => TimeTest(a3));
    
        Console.WriteLine("***4 Args***");
        Action p4 = () => path = Path.Combine(new[] { Root, seg, seg, seg });
        test("params4", () => TimeTest(p4));
        Action a4 = () => path = Path.Combine(Root, seg, seg, seg);
        test("args4  ", () => TimeTest(a4));
    
        Console.WriteLine(path);
    }
    
    [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.GC.Collect")]
    private static double TimeTest(Action action)
    {
        const int Iterations = 10 * 1000 * 1000;
    
        Action gc = () =>
        {
            GC.Collect();
            GC.WaitForFullGCComplete();
        };
    
        Action empty = () => { };
    
        Stopwatch stopwatch1 = Stopwatch.StartNew();
    
        for (int j = 0; j < Iterations; j++)
        {
            empty();
        }
    
        double loopElapsed = stopwatch1.Elapsed.TotalMilliseconds;
    
        gc();
    
        action(); //JIT
        action(); //Optimize
    
        Stopwatch stopwatch2 = Stopwatch.StartNew();
    
        for (int j = 0; j < Iterations; j++)
        {
            action();
        }
    
        gc();
    
        double testElapsed = stopwatch2.Elapsed.TotalMilliseconds;
    
        return (testElapsed - loopElapsed);
    }
    

    关于c# - 为什么System.IO.Path.Combine有4个重载?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4462990/

    10-11 05:49