Βελτιστοποίηση Συγκεντρωτικά για String Αλληλουχία

ψήφοι
18

Ενημέρωση - για όσους από μια περιπαικτική πλαίσιο του μυαλού, μπορείτε να υποθέσετε ότι Συγκεντρωτικά εξακολουθεί να παράγει το φυσιολογικό αποτέλεσμα ό, τι η λειτουργία περνάει σε αυτό, ακόμη και στην περίπτωση που βελτιστοποιείται.

Έγραψα αυτό το πρόγραμμα για να χτίσει μια μακρά σειρά των ακεραίων 0-19999 ξεχωριστά με κόμμα.

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

Όταν το τρέχω, λέει:

5116ms

Πάνω από πέντε δευτερόλεπτα τρομερό. Φυσικά αυτό συμβαίνει γιατί όλο το κείμενο αντιγράφεται κάθε φορά γύρω από το βρόχο.

Τι γίνεται όμως αν κάνουν μια πολύ μικρή αλλαγή που υποδεικνύεται από το σχόλιο;

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

Τώρα, όταν το τρέξετε, λέει:

42ms

Πάνω από 100 φορές πιο γρήγορα.

Ερώτηση

Τι είναι στο χώρο ονομάτων MakeAggregateGoFaster;

Ενημέρωση 2: Έγραψε πάνω απάντησή μου εδώ .

Δημοσιεύθηκε 10/12/2008 στις 00:12
πηγή χρήστη
Σε άλλες γλώσσες...                            


5 απαντήσεις

ψήφοι
40

Γιατί να μην χρησιμοποιήσετε μία από τις άλλες μορφές των αδρανών;

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

Μπορείτε να καθορίσετε οποιοδήποτε τύπο για τους σπόρους σας, κάντε ό, τι οι μορφοποίηση ή έθιμο κλήσεις που απαιτούνται στην πρώτη λειτουργία λάμδα και στη συνέχεια να προσαρμόσετε τον τύπο εξόδου στη δεύτερη λειτουργία λάμδα. Το ενσωματωμένο χαρακτηριστικά που ήδη παρέχει την ευελιξία που χρειάζεστε. τρεξίματα μου πήγε από 1444ms σε 6ms.

Απαντήθηκε 14/01/2009 στις 18:18
πηγή χρήστη

ψήφοι
15

Θα είναι «επιτακτικό» System.Linq.Aggregate με το δικό του τρόπο την επέκτασή σας στο χώρο ονομάτων MakeAggregateGoFaster.

Ίσως ειδικεύεται σε IEnumerable<string>και κάνοντας χρήση ενός StringBuilder;

Ίσως παίρνετε ένα Expression<Func<string, string, string>>αντί για ένα Func<string, string, string>, ώστε να μπορεί να αναλύσει το δέντρο έκφρασης και την κατάρτιση κάποιο κώδικα που χρησιμοποιεί StringBuilder αντί καλώντας τη λειτουργία άμεσα;

Απλα μαντευω.

Απαντήθηκε 10/12/2008 στις 00:30
πηγή χρήστη

ψήφοι
5

Δεν απαντώντας στην ερώτηση, αλλά νομίζω ότι το πρότυπο σχέδια είναι εδώ για να χρησιμοποιήσετε StringBuilder ή string.Join:

string.join(", ",Enumerable.Range(0, size).Select(n => n.ToString()).ToArray())
Απαντήθηκε 10/12/2008 στις 00:16
πηγή χρήστη

ψήφοι
4

Ο λόγος για τον ρώτησα αν ήταν ένας γρίφος ήταν γιατί ένα παζλ επιτρέπεται να θυσιάσει ευρωστία σε διάφορους βαθμούς, αρκεί να ικανοποιεί την επιστολή του ανέφερε το πρόβλημα. Με αυτό κατά νου, εδώ πηγαίνει:

Λύση 1 (τρέχει αμέσως, το πρόβλημα δεν επικυρώνει):

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

Λύση 2 (τρέχει τόσο γρήγορα όσο το πρόβλημα απαιτεί, αλλά αγνοεί τον εκπρόσωπο πλήρως):

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();
}
Απαντήθηκε 10/12/2008 στις 00:35
πηγή χρήστη

ψήφοι
3

Λοιπόν, αυτό θα εξαρτηθεί εξ ολοκλήρου από το τι κωδικός είναι στο χώρο ονομάτων MageAggregateGoFaster τώρα δεν θα είναι;

Αυτό ονομάτων δεν αποτελεί μέρος του .NET runtime, έτσι ώστε να έχετε συνδέσει με κάποιο προσαρμοσμένο κώδικα.

Προσωπικά θα ήθελα να πιστεύω ότι κάτι που αναγνωρίζει συνένωση κορδόνι ή παρόμοιο, και δημιουργεί μια λίστα, ή παρόμοιο, τότε διαθέτει ένα μεγάλο StringBuilder και χρησιμοποιεί Προσάρτηση.

Μια βρώμικη λύση θα ήταν:

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

βρώμικο, γιατί αυτός ο κώδικας, ενώ κάνει ό, τι λέτε εσείς αντιμετωπίζετε με το πρόγραμμά σας, δεν χρησιμοποιεί τον εκπρόσωπο λειτουργία σε όλα. Θα πρέπει, ωστόσο, να μειωθεί ο χρόνος εκτέλεσης από όλο 2800ms σε 11ms στον υπολογιστή μου, και εξακολουθούν να παράγουν τα ίδια αποτελέσματα.

Τώρα, την επόμενη φορά, ίσως θα πρέπει να ζητήσετε ένα πραγματικό ερώτημα και όχι απλά κοιτάξτε πόσο έξυπνος είμαι ο τύπος του στήθους, ήττα;

Απαντήθηκε 10/12/2008 στις 00:15
πηγή χρήστη

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