Dize bitiştirme için optimize Agrega

oy
18

Güncelleme - aklın alaycı çerçevenin olanlar için, size Agrega hala işlev optimize edilen durumda da dahil, kendisine geçirilen ne olursa olsun, normal bir sonuç üretir varsayabiliriz.

Ben virgülle 0 19999 ayrı arasındaki tam sayıların uzun dizesi oluşturmak için bu programı yazdım.

using System;
using System.Linq;
using System.Diagnostics;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {
            const int size = 20000;

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            Enumerable.Range(0, size).Select(n => n.ToString()).Aggregate((a, b) => a + ,  + b);
            stopwatch.Stop();

            Console.WriteLine(stopwatch.ElapsedMilliseconds + ms);
        }
    }
}

Onu çalıştırdığınızda, diyor ki:

5116ms

Beş saniye içinde, korkunç. Bütün dize döngü etrafında her zaman kopyalanan çünkü Tabii ki bu.

Ama yorumun ile gösterilen bir çok küçük bir değişiklik ne yaparsanız?

using System;
using System.Linq;
using System.Diagnostics;

namespace ConsoleApplication5
{
    using MakeAggregateGoFaster;  // <---- inserted this

    class Program
    {
        static void Main(string[] args)
        {
            const int size = 20000;

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            Enumerable.Range(0, size).Select(n => n.ToString()).Aggregate((a, b) => a + ,  + b);
            stopwatch.Stop();

            Console.WriteLine(stopwatch.ElapsedMilliseconds + ms);
        }
    }
}

Bunu çalıştırdığınızda Şimdi, diyor ki:

42ms

Daha hızlı 100x üzerinde.

Soru

MakeAggregateGoFaster ad ne var?

Güncelleme 2: Burada cevabımı kadar yazdım .

Oluştur 10/12/2008 saat 00:12
kaynak kullanıcı
Diğer dillerde...                            


5 cevaplar

oy
40

Neden Agrega diğer şekillerinden birini kullanabilirsiniz?

Enumerable.Range(0, size ).Aggregate(new StringBuilder(),
        (a, b) => a.Append(", " + b.ToString()),
        (a) => a.Remove(0,2).ToString());

Sen, tohum herhangi türünü belirtmek biçimlendirme veya özel aramalar ilk lambda fonksiyonunda gerekli her türlü gerçekleştirmek ve daha sonra ikinci lamda fonksiyonunda çıktı türünü özelleştirebilirsiniz. Zaten ihtiyacınız esneklik sağlamak özellikleri yerleşik. Benim çalışır 6ms için 1444ms gitti.

Cevap 14/01/2009 saat 18:18
kaynak kullanıcı

oy
15

Sen ad MakeAggregateGoFaster kendi uzantısı yöntemi ile System.Linq.Aggregate 'ağır basan' vardır.

Belki üzerinde uzmanlaşmış IEnumerable<string>ve bir StringBuilder yararlanarak?

Belki bir alarak Expression<Func<string, string, string>>yerine ait Func<string, string, string>böylece ifade ağacı analiz etmek ve işlevi doğrudan çağırma StringBuilder yerine kullandığı bazı kod derlemek olabilir?

Sadece tahmin ediyorum.

Cevap 10/12/2008 saat 00:30
kaynak kullanıcı

oy
5

soruya cevap, ama burada standart desenler StringBuilder veya string.join kullanmak olduğunu düşünüyorum Değil:

string.join(", ",Enumerable.Range(0, size).Select(n => n.ToString()).ToArray())
Cevap 10/12/2008 saat 00:16
kaynak kullanıcı

oy
4

bir bulmaca sürece belirtilen problemin mektubu tatmin olarak değişen derecelerde sağlamlığı kurban izin çünkü bir bulmaca olup olmadığını sordum neden oldu. Bunu göz önünde bulundurarak, buraya:

Çözüm 1 (problem doğrulamaz anında çalışır):

public static string Aggregate(this IEnumerable<string> l, Func<string, string, string> f) {
     return "";
}

Çözüm 2 (hızlı sorun gereğine göre yaklaşık çalışır, ama tamamen temsilci yok sayar):

public static string Aggregate(this IEnumerable<string> l, Func<string, string, string> f) {
    StringBuilder sb = new StringBuilder();
    foreach (string item in l)
        sb.Append(", ").Append(item);
    return sb.Remove(0,2).ToString();
}
Cevap 10/12/2008 saat 00:35
kaynak kullanıcı

oy
3

Pekala, bu olmaz şimdi MageAggregateGoFaster ad alanında ne kod tamamen bağlı olacağı?

Bu ad .NET çalışma zamanı parçası değil, bu nedenle bazı özel kodunda bağlantı oluşturduk.

Şahsen dize birleştirme veya benzeri tanır ve bir liste veya benzeri kurar şey, daha sonra büyük bir StringBuilder ayırır ve Append kullandığı düşünürdüm.

Kirli bir çözüm olacaktır:

namespace MakeAggregateGoFaster
{
    public static class Extensions
    {
        public static String Aggregate(this IEnumerable<String> source, Func<String, String, String> fn)
        {
            StringBuilder sb = new StringBuilder();
            foreach (String s in source)
            {
                if (sb.Length > 0)
                    sb.Append(", ");
                sb.Append(s);
            }

            return sb.ToString();
        }
    }
}

Eğer program ile yaşamaya dediklerini yaparken bu kod, hiç fonksiyonu temsilci kullanmadığı için kirli. Bununla beraber, bilgisayarımda 11ms yaklaşık 2800ms gelen yürütme zamanı çökertmek ve hala aynı sonuçları üretecektir.

Şimdi, bir sonraki sefer, belki gerçek soru sormalısınız yerine sadece ne kadar zeki görünmek göğüs dayak tipi?

Cevap 10/12/2008 saat 00:15
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more