Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Code optimization (text replace and count)

Îåêßíçóå áðü ôï ìÝëïò Dimitris Papadimitriou. Τελευταία δημοσίευση από το μέλος Mitsaras στις 02-08-2008, 12:49. Υπάρχουν 23 απαντήσεις.
Σελίδα 1 από 2 (24 εγγραφές)   1 2 >
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  01-08-2008, 10:59 43857

    Code optimization (text replace and count)

    Παραθέτω ένα κομμάτι κώδικα που είχα γράψει πριν πολύ πολύ καιρό και ζητώ τις ιδέες σας. Λέτε να μπορεί να γίνει κάποιο optimization; Η γλώσσα είναι C# και δεκτό είναι οποιοδήποτε optimization χρησιμοποιώντας οποιαδήποτε έκδοση της γλώσσας.

            public static int CountMatches(string inputText, string searchText)
            {
                var newLength = inputText.Replace(searchText, string.Empty).Length;
                return (inputText.Length - newLength)/searchText.Length;
            }

    Η συνάρτηση υπολογίζει πόσες φορές το searchText βρίσκεται μέσα στο inputText. Για να το κάνει αυτό κάνει replace το searchText string μέσα στο inputText, βρίσκει το μήκος του νέου κειμένου. Η διαφορά το αρχικού μήκους με το τελικό διά το μήκος του searchText είναι ο αριθμός που βρήθηκε το searchText στο inputText.

    (Πριν γίνουν όλα αυτά γίνονται κάποιοι έλεγχοι για null input τιμές, αλλά αφαίρεσα τον κώδικα για λόγους απλότητας)

    Η συνάρτηση λειτουργεί ταχύτατα ακόμα και για τεράστια inputText (π.χ. 10MB). Λέτε όμως να μπορεί να γίνει κάποιο optimization;

    ps. Οι συμμετέχοντας θα μπουν σε κλήρωση για 6ήμερες διακοπές στο ακριτικό Σύνταγμα σε παγκάκι Α κατηγορίας (ε... καλά δεν μου ερχόταν κάτι πιο αστείο να γράψω).


    Dimitris Papadimitriou
    Software Development Professional
    dotNETZone.gr News

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Διαβάστε επίσης τους όρους χρήσης.
  •  01-08-2008, 11:16 43859 σε απάντηση της 43857

    Απ: Code optimization (text replace and count)

    Γιατί δεν δοκιμάζεις με Regex?


    Vir prudens non contra ventum mingit
  •  01-08-2008, 11:23 43860 σε απάντηση της 43859

    Απ: Code optimization (text replace and count)

    Μου άρεσε η υλοποίηση, πολύ έξυπνη προσέγγιση! Μπορείς να δοκιμάσεις και με string.Split(...).Count() -1 αλλά φαντάζομαι η μνήμη δεν είναι το δυνατό σημείο μιας τέτοιας λύσης.

    EDIT. Να και ένα μίνι benchmark. Για ένα αρχείο 50ΜΒ με όλα τα πιθανά compiler optimizations, τα αποτελέσματα σε msec είναι:
    Count Matches: 212
    String split: 328
    Regex: 106

    Βέβαια, το Regex έδωσε πολύ καλά αποτελέσματα σε "δύσκολα" strings τα οποία δεν επαναλαμβάνονται συχνά στο κείμενο. Στην χειρότερη περίπτωση (ψάχνοντας για ένα γράμμα στο ίδιο αρχείο), τα αποτελέσματα ήταν:
    Count Matches: 204
    String split: 326
    Regex: 367

    Κατά κανόνα όμως, το Regex στην περίπτωσή μου επιτύγχανε τις καλύτερες επιδόσεις.

    Μην αφήνετε τα media να σας "ταΐζουν"!
  •  01-08-2008, 12:37 43861 σε απάντηση της 43860

    Απ: Code optimization (text replace and count)

    Mitsara thanks για το benchmark!

    Κοιτάξτε τώρα τι μπορεί να πάθει κανείς. Αυτή τη λύση την κάνω από την VB6. Ούτε μου πέρασε από το μυαλό αν χρησιμοποιήσω RegEx στο .NET, αν και χρησιμοποιώ σε άλλες περιπτώσεις!

    Θα πρέπει να κάνουμε και ένα memory profiling να δούμε τι γίνεται (π.χ. χρησιμοποιώντας το εκπληκτικό dotTrace)! Μήπως κανείς μπορεί να πει απευθείας;


    Dimitris Papadimitriou
    Software Development Professional
    dotNETZone.gr News

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Διαβάστε επίσης τους όρους χρήσης.
  •  01-08-2008, 13:11 43863 σε απάντηση της 43861

    Απ: Code optimization (text replace and count)

    Δημήτρη δες και αυτό που έγραψα...

    public static int CountMatches(string inputText, string searchText)
    {
       int position = -1;
       int startIndex = 0;
       int counter = 0;
       while((position = inputText.IndexOf(searchText, startIndex)) != -1)
       {
          counter++;
          startIndex = position + 1;
       }
       return counter;
    }

    (Λογικά η IndexOf πρέπει να χρησιμοποιεί Knuth-Morris-Pratt... οποτε είναι optimal)


    Palladinos Nick
    Software Engineer
    -----------------------
    The limits of my language mean the limits of my world. (Ludwig Wittgenstein)
  •  01-08-2008, 13:25 43864 σε απάντηση της 43863

    Απ: Code optimization (text replace and count)

    Thanks Νίκο,

    της σκέφτηκα αυτή τη λύση αλλά επειδή δεν τους ήξερα τους κυρίους που αναφέρεις την απέρριψα γιατί θεώρησα ότι θα είναι αργή. Αλλά τώρα που απέκτησε και ονοματεπώνυμο μάλλον πρέπει να την δοκιμάσω.

    (καλά δεν είναι ότι έχω τόσο μεγάλο πρόβλημα αυτή τη στιγμή, απλά το θεώρησα ωραίο θέμα για συζήτηση).


    Dimitris Papadimitriou
    Software Development Professional
    dotNETZone.gr News

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Διαβάστε επίσης τους όρους χρήσης.
  •  01-08-2008, 13:43 43868 σε απάντηση της 43864

    Απ: Code optimization (text replace and count)

    Χμ, συγκρίνοντας τις δύο λύσεις, του Δημήτρη και του Νίκου, παρατηρώ ότι αυτή του Νίκου επιτυγχάνει καλύτερα αποτελέσματα σε σημεία όπου η προς αναζήτηση λέξη είναι μικρή σε συχνότητα στο κείμενο, όπου και αποτελεί την ιδανική πιθανότητα, κατά τ'άλλα προσεγγίζουν η μία την άλλη. Σε σχέση με το regex, η λύση του Νίκου είναι πιο σταθερή, καθώς, αν ορίσουμε ως ανώτατο όριο την πρώτη λύση, δεν την ξεπερνάει ποτέ σε χρόνο (κάτι που συμβαίνει με το regex).

    Νίκο, kudos to you sir (ειδικά για το διάβασμα για τον αλγόριθμο, τον οποίο αγνοούσα)! Μου άρεσε πάρα πολύ ο μηχανισμός στην πρώτη λύση του Δημήτρη όμως, που μπορεί κάλλιστα να γίνει και one-liner. Προς το παρόν, παίρνω την αργή και memory inefficient λύση μου και πάω πίσω στη γωνιά μου Cool.

    Μην αφήνετε τα media να σας "ταΐζουν"!
  •  01-08-2008, 13:44 43869 σε απάντηση της 43864

    Απ: Code optimization (text replace and count)

    Χμμ, κάνοντας την υπόθεση ότι η IndexOf δουλεύει με χαζό τρόπο, όντως θα ήταν αργή. Αλλά δεν δουλεύει με χαζό τρόπο. Σύμφωνα με τη Wikipedia η ταχύτητα του KMP είναι O(n+k) όπου n και k το μήκος των δύο string. Το θέμα είναι, οι ψ επαναλήψεις για να κάνεις το count θα βγουν γρηγορότερες από το Regex?

     


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  01-08-2008, 13:53 43871 σε απάντηση της 43868

    Απ: Code optimization (text replace and count)

    H πρώτη λύση, πέρα από το ότι δημιουργεί άλλο ένα μεγάλο temporary string, προκαλεί και ένα βαρύ memory allocation και ένα βαρύ garbage collection όταν χρησιμοποιούνται μεγάλα strings και πιθανώς και fragmentation της μνήμης. Αν τη δει κανείς μόνη της ίσως να μην φαίνεται τόσο αργή, αν σκεφτείς όμως ότι αυτός ο κώδικας εκτελείται στα πλαίσια μίας εφαρμογής και μπορεί να κληθεί πολλές φορές το δευτερόλεπτο ...

     


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  01-08-2008, 14:09 43873 σε απάντηση της 43871

    Απ: Code optimization (text replace and count)

    Παναγιώτης Καναβός:

    H πρώτη λύση, πέρα από το ότι δημιουργεί άλλο ένα μεγάλο temporary string, προκαλεί και ένα βαρύ memory allocation και ένα βαρύ garbage collection όταν χρησιμοποιούνται μεγάλα strings και πιθανώς και fragmentation της μνήμης. Αν τη δει κανείς μόνη της ίσως να μην φαίνεται τόσο αργή, αν σκεφτείς όμως ότι αυτός ο κώδικας εκτελείται στα πλαίσια μίας εφαρμογής και μπορεί να κληθεί πολλές φορές το δευτερόλεπτο ...

    Και αυτός είναι κυρίως ο λόγος που με έκανε να αναζητήσω κάτι καλύτερο.


    Dimitris Papadimitriou
    Software Development Professional
    dotNETZone.gr News

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Διαβάστε επίσης τους όρους χρήσης.
  •  01-08-2008, 19:38 43880 σε απάντηση της 43863

    Απ: Code optimization (text replace and count)

    PALLADIN:

    Δημήτρη δες και αυτό που έγραψα...

    public static int CountMatches(string inputText, string searchText)
    {
       int position = -1;
       int startIndex = 0;
       int counter = 0;
       while((position = inputText.IndexOf(searchText, startIndex)) != -1)
       {
          counter++;
          startIndex = position + 1;
       }
       return counter;
    }

    (Λογικά η IndexOf πρέπει να χρησιμοποιεί Knuth-Morris-Pratt... οποτε είναι optimal)



    .. κι αν κάνεις το  startIndex = position + 1; -> startIndex = position + searchText.Length; δε θα "κόψει" κι άλλο χρόνο; Μπορεί να παραλογίζομαι βέβαια, είμαι "στα πεταχτά" εδώ ... :)

    Angel
    O:]
  •  01-08-2008, 20:21 43881 σε απάντηση της 43880

    Απ: Code optimization (text replace and count)

    anjelinio:


    .. κι αν κάνεις το  startIndex = position + 1; -> startIndex = position + searchText.Length; δε θα "κόψει" κι άλλο χρόνο; Μπορεί να παραλογίζομαι βέβαια, είμαι "στα πεταχτά" εδώ ... :)

    Πόσες φορες εμφανίζεται το "NNΝ" στο "ΝNNNNN" 2 ή 4 ?


    Palladinos Nick
    Software Engineer
    -----------------------
    The limits of my language mean the limits of my world. (Ludwig Wittgenstein)
  •  01-08-2008, 20:24 43882 σε απάντηση της 43881

    Απ: Code optimization (text replace and count)

    Σωστοοοοος ! Big Smile

    Angel
    O:]
  •  01-08-2008, 20:27 43884 σε απάντηση της 43882

    Απ: Code optimization (text replace and count)

    Φαντάζομαι ότι εγώ πρέπει να το απαντήσω αυτό. Νομίζω 2.

    Dimitris Papadimitriou
    Software Development Professional
    dotNETZone.gr News

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Διαβάστε επίσης τους όρους χρήσης.
  •  01-08-2008, 20:28 43885 σε απάντηση της 43882

    Απ: Code optimization (text replace and count)

    Φεύγοντας από την δουλειά... να ευχηθώ ένα καλο ΣΚ σε όλους σας


    Palladinos Nick
    Software Engineer
    -----------------------
    The limits of my language mean the limits of my world. (Ludwig Wittgenstein)
Σελίδα 1 από 2 (24 εγγραφές)   1 2 >
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems