pathcombine net example convert combine asp c# .net

c# - example - path combine asp net



¿Por qué System.IO.Path.Combine tiene 4 sobrecargas? (6)

¿Qué pasa con shugar sintáctico para idiomas que no admiten algo similar a la palabra clave c # - "params"

Actualizar

Se eliminó el problema de rendimiento ya que solo medí la versión de 4 parámetros, pero no la versión de 3 y 2 parámetros que son realmente más rápidas

El rendimiento no es la razón. (Ver mi punto de referencia a continuación)

Punto de referencia

Medí el rendimiento. Para mi sorpresa, la versión array fue ligeramente mejor.

[TestMethod] public void MeasurePathPerfomance() { // repeat several times to avoid jit-issues for (int j = 0; j < 10; j++) { { DateTime start = DateTime.Now; string result; for (int i = 0; i < 30000; i++) { result = System.IO.Path.Combine("a", "b", "c", "d"); // use 4 parameter version } TimeSpan spend = DateTime.Now - start; System.Console.WriteLine("4 param : {0}", spend.TotalMilliseconds); } { DateTime start = DateTime.Now; string result; for (int i = 0; i < 30000; i++) { result = System.IO.Path.Combine(new string[] { "a", "b", "c", "d" }); } TimeSpan spend = DateTime.Now - start; System.Console.WriteLine("array[4] param : {0}", spend.TotalMilliseconds); } } }

resultado

4 param : 10.001 array[4] param : 9.0009 4 param : 12.0012 array[4] param : 8.0008 4 param : 12.0012 array[4] param : 10.001 4 param : 11.0011 array[4] param : 9.0009 4 param : 11.0011 array[4] param : 11.0011 4 param : 11.0011 array[4] param : 9.0009 4 param : 10.001 array[4] param : 8.0008 4 param : 10.001 array[4] param : 9.0009 4 param : 11.0011 array[4] param : 9.0009 4 param : 11.0011 array[4] param : 9.0009

En .NET 4, System.IO.Path tiene las siguientes sobrecargas para el método 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)

El primero se agregó en .NET 4 para admitir cualquier número de argumentos de ruta. El segundo ya estaba allí en versiones anteriores, así que supongo que se mantiene por compatibilidad con versiones anteriores.

Pero tengo curiosidad por saber cuál es el uso de las otras sobrecargas. ¿Estos casos de uso ya no están cubiertos por la primera firma de método con params ?

edición: ahora creo que la respuesta es "porque no todos los idiomas tienen soporte de params (y no es conveniente pasar una matriz sin el soporte de parámetros)". Sin embargo, la mente de la colmena de stackoverflow parece estar en desacuerdo. Por lo tanto, como compromiso, no estoy aceptando ninguna respuesta.


Creo que la razón es que la mayoría de los programadores usan uno, dos, tres o cuatro valores para combinar y más que eso, usted desea pensar que es mejor implementar una matriz en lugar de usar más valores.

Ejemplo

Sum(a , b); //fine Sum(a , b , c);//fine Sum(a , b , c , d);//fine Sum(a , b , c , d ,....); //now I think you think everyone think even Microsoft also thinks, its better to implement array here // something like this Sum(params var[] n);

Así que encontrarás que la mayor parte del método contiene 1,2,3,4 argumentos y luego params


Es solo por el rendimiento, el rendimiento de los últimos 3 es mayor que el primer método.

Si desea conocer la implementación, simplemente mscorlib con reflector, verá que el rendimiento será mejor en las últimas 3 funciones


La compatibilidad hacia atrás es la mejor razón que se me ocurre. Las sobrecargas probablemente están llamando al primer método.


Sospecharía de rendimiento, ya que tiene que crear una matriz intermedia con parámetros, más la sobrecarga de atravesar la matriz, etc. Probablemente hay algunos casos internos, etc., en los que existe un buen caso para usar las versiones de parámetros numerados fijos.

Actualizar

Ahora he realizado pruebas de rendimiento para verificar mis suposiciones. Esto es algo que debería haber hecho en primer lugar: rompí mi propio mantra de desempeño:

No pienses - mide.

Mis suposiciones no son del todo correctas, pero no del todo equivocadas. La versión de 4 parámetros fijos es ligeramente más lenta que la versión de 4 parámetros, pero las variaciones fijas de 3 y 2 funcionan significativamente mejor.

Hay una serie de problemas con el arnés de prueba de rendimiento para la respuesta aceptada actual que indica que el rendimiento va totalmente a favor de la versión params. Esto es incorrecto:

  • Utiliza DateTime. Ahora para el cronometraje. Siempre use un Cronómetro para realizar micro evaluaciones comparativas como DatTime. Ahora solo es preciso entre ~ 10ms-> 15ms. Hay un sinfín de artículos sobre esto .
  • La prueba solo cubre el caso de la versión de 4 parámetros. ¿Qué pasa con las versiones de 3 y 2 parámetros?
  • La generación y recolección de basura no son tomadas en consideración. Un método puede ser más rápido en una línea recta entre A-> B, pero también puede generar una gran cantidad de basura que tendrá que limpiarse en algún momento. Esta es una penalización de rendimiento diferida, pero sigue siendo un impacto en el rendimiento, por lo que debe tenerse en cuenta.
  • Asegúrese de que los argumentos tengan valores realistas: ¿es realista combinar rutas de un solo carácter?

Tengo los siguientes resultados de desempeño, los cuales incluí variaciones de 2, 3 y 4 argumentos donde se puede ver que el desempeño es significativamente mejor para 2 y 3 variaciones, y marginalmente peor para las 4 variaciones. Sin embargo, las versiones de argumento de número fijo son más rápidas en general, siendo 3 la más significativa en términos de esta pregunta (la variación de 2 argumentos existió desde .Net 1.1).

***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

Prueba:

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); }


Una posible razón también puede ser reducir la presión sobre el recolector de basura. La sobrecarga params-array crea una nueva matriz cada vez que se llama al método. Si el método se llama a menudo, se crean muchos objetos de matriz temporales, lo que aumenta la presión sobre el recolector de basura.