¿Soy yo o la respuesta elegida está rota? Pasa el 99% del tiempo calculando la longitud de entrada, y no debería incluir 'lo mismo' en llamadas posteriores. ¡Nunca termina!
Me doy cuenta de que es poco ortodoxo convertir a la lista <> de IEnumerable <> pero funciona si no te molesta la copia. Tal vez haya una forma de .FirstOrDefault() + .Skip (1) .FirstOrDefault() para calcular si tiene 0 o 1 de longitud sin hacer el trabajo masivo para .Length()? ¿Es esto más rápido que morder la bala y usar .Length()? tal vez no ...
La comparación de velocidad entre una consulta adecuada en lugar de .ForEach no es concluyente. Una entrada más grande puede ser necesaria para ver?
polvo rápido:
case 0: ites.ForEach(k => { if (k < piv) les.Add(k); }); break;
case 1: ites.ForEach(k => { if (k == piv) sam.Add(k); }); break;
case 2: ites.ForEach(k => { if (k > piv) mor.Add(k); }); break;
quickie2:
private static List<int> quickie2(List<int> ites)
{
if (ites.Count <= 1)
return ites;
var piv = ites[0];
List<int> les = new List<int>();
List<int> sam = new List<int>();
List<int> mor = new List<int>();
Enumerable.Range(0, 3).AsParallel().ForAll(i =>
{
switch (i)
{
case 0: les = (from _item in ites where _item < piv select _item).ToList(); break;
case 1: sam = (from _item in ites where _item == piv select _item).ToList(); break;
case 2: mor = (from _item in ites where _item > piv select _item).ToList(); break;
}
});
List<int> allofem = new List<int>();
var _les = new List<int>();
var _mor = new List<int>();
ConcurrentBag<ManualResetEvent> finishes = new ConcurrentBag<ManualResetEvent>();
for (int i = 0; i < 2; i++)
{
var fin = new ManualResetEvent(false);
finishes.Add(fin);
(new Thread(new ThreadStart(() =>
{
if (i == 0)
_les = quickie(les);
else if (i == 1)
_mor = quickie(mor);
fin.Set();
}))).Start();
}
finishes.ToList().ForEach(k => k.WaitOne());
allofem.AddRange(_les);
allofem.AddRange(sam);
allofem.AddRange(_mor);
return allofem;
}
longitud de entrada: 134217728
polvo rápido: 00: 00: 08,2481166 quickie2: 00: 00: 05,0694132
polvo rápido : 00: 00: 03.4997753 quickie2: 00: 00: 0 4.3986761
rapidito: 00: 00: 06,9764478 quickie2: 00: 00: 04,8243235
rapidito: 00: 00: 08,2962985 quickie2: 00: 00: 04,0703919
rapidito: 00: 00: 04,2339839 quickie2: 00: 00: 08,5462999
rapidito: 00: 00: 07,0605611 quickie2: 00: 00: 05,0110331
rapidito: 00: 00: 03,1742108 quickie2: 00: 00: 06,9817196
rapidito: 00: 00: 06,9593572 quickie2: 00: 00: 05,8098719
rapidito: 00: 00: 03,4487516 quickie2: 00: 00: 04,1156969
Quickie: 00: 00: 03.1562592 quickie2: 00: 00: 05.6059656
Esto es lo peor, mientras escribía la respuesta que Panos completó y publicó su respuesta, exactamente igual que la mía :-( –
¿Hay alguna diferencia además de la sintaxis entre esta representación explícita de LINQ en oposición a las expresiones de Lambda en Panos ' versión? Es o más eficiente que el otro? – Skeolan
Voy a aceptar esta respuesta, porque es lo que es básicamente lo que quería. Pero las otras respuestas fueron geniales! – Dana