Wie schnell können Sie lineare Suche?

Ich bin auf der Suche um dies zu optimieren, lineare Suche:

static int
linear (const int *arr, int n, int key)
{
        int i = 0;
        while (i < n) {
                if (arr [i] >= key)
                        break;
                ++i;
        }
        return i;
}

Das array sortiert ist und die Funktion zurückgeben sollte, wird der index des ersten Elements größer oder gleich dem Schlüssel. Sie-array ist nicht groß (unter 200 Elemente) und wird bereit sein, einmal für eine große Anzahl von Suchanfragen. Array-Elemente nach dem n-TEN kann bei Bedarf initialisiert werden, um etwas passendes, wenn das beschleunigt die Suche.

Keine, binäre Suche ist nicht erlaubt, nur lineare Suche.

Bearbeiten: All mein wissen über dieses Thema ist jetzt zusammengefasst in diesem blog-post.

  • Wo ist die Frage?
  • Die einzige Sache, die Sie tun können, ist, profitieren Sie von allen SIMD-Befehle zur Verfügung, die auf Ihre Plattform. (Test vier gleichzeitig, zum Beispiel.) Obwohl, warum würden Sie nicht die binäre Suche, weiß ich nicht.
  • Sie nicht haben, um zu testen, jedes element; Sie können testen, alle kth-element, wenn Sie sind dann erlaubt, wieder zu gehen. Auch, wenn Sie wissen, die Anzahl der Elemente, die Sie können ein array / hash-Tabelle, die nur gibt Ihnen die Antwort. Aber, könnte man nicht überlegen, diese "lineare Suche".
  • Warum ist die binäre Suche (willkürlich?) nicht erlaubt ist? Ist das ein echtes problem oder irgendeine Art von Hausaufgaben? Denn wenn du gehst, zu gehen durch die Mühe der Sortierung der Daten, wird eine binäre Suche ist dein bester Darsteller.
  • (Random thought: eins, zwei, überspringen Sie ein paar-aber das könnte fallen in 'nicht-linear', und wenn es schon sortiert, da jede nicht-triviale n ohne das match zu erwarten in der Nähe der front und der zugehörigen Lokalität Fragen ...)
  • Das ist im Grunde eine binäre Suche, wobei "ein paar" ist die "verbleibenden array-Größe / 2".
  • Binäre searsh wird am besten ausgeführt werden, nur wenn Sie wissen, dass das element, das Sie suchen, befindet sich in einem komplett unvorhersehbaren position. Wenn Sie wissen, dass die target-element ist wahrscheinlich in der Nähe der Anfang des Arrays, lineare Suche besser abschneiden werden als die binäre Suche. Klassisches Beispiel ist der bekannte Algorithmus für das Zusammenführen von zwei sortierten arrays. Wenn die arrays haben in etwa die gleiche Länge, die Verschmelzung erfolgt mit linearen Suche, da binäre wird viel langsamer.
  • Denken Sie daran binäre Suche erfordert Ihre eingestellten Daten sortiert werden.
  • tatsächlich, ich habe irgendwo gelesen, dass für kleine Arrays, lineare Suche schneller sein können: lwn.net/Articles/255364 - (Diskussion in den Kommentaren)
  • Wäre es als Cheaten angesehen, wenn Sie gescannt werden (jedes zehnte element erste und nach dem finden der ersten nicht weniger als der Schlüssel, gehen Sie zurück und Scannen letzten zehn element eins nach dem anderen? Wie wäre es mit einer Quadratwurzel von n anstelle von 10?
  • Das ist toll für bestimmte Fälle, aber es gibt nichts zu zeigen, dass es etwas besonderes über diesen Datensatz. Im generischen Fall, ein sortiert, aber sonst Fußgänger Satz von Daten wird am besten funktionieren in den meisten Anwendungsfällen mit einer binären Suche.
  • Ja, nicht das Scannen jedes element wäre Cheaten. @GMan: Es gibt eine MENGE Sie tun können, bevor Rückgriff auf SIMD. @Joe: Das ist der "Hausaufgaben", die ich gegeben habe, mich, den hab ich auch schon gemacht. Ich bin nur neugierig, was die Leute kommen mit, die ich noch nicht gedacht.
  • Alles, was Sie tun, im Grunde genommen ein umsponnen binäre Suche.
  • Finden Sie die top-bewerteten Antwort, zum Beispiel. Viel schneller als die einfache lineare Suche (ich weiß, ich habe gemessen).
  • Ich bin überrascht, dass. Was würde das abrollen vier machen?
  • Abrollen von vier Geschwindigkeiten um fast 50% bei N=100 auf einem Core i7. Abrollen, indem vier mit einer sentinel-Geschwindigkeiten von bis von mehr als 50%.
  • Noch keine Lösungen, die mehrere threads verwenden?
  • Probst: Ja abrollen können die Sache beschleunigen, ich glaube ich muss wieder Lesen mein Code Complete Buch 🙂 Hier ist das abrollen Thema aus diesem Buch stevemcconnell.com/cctune.htm
  • Ja, aber sehen Sie das problem: Sie haben zu implementieren lineare Suche in einem sortierten array. Dies ist bereits ausreichend nicht-generische. Diese bereits schon etwas besonderes. Warum würde jemand darauf bestehen, eine lineare Suche in einem sortierten array? Vielleicht tun Sie es, weil die Struktur der Abfragen bevorzugt lineare Suche speziell? Zum Beispiel, wenn Sie eine geordnete Reihe von N Elemente haben, um in der Nähe N bestellt, Suche, Abfragen, inkrementelle lineare Suche besser abschneiden werden als binäre Suche um ein Vielfaches, mindestens.
  • Probst: Sie erarbeiten mit Optimierungen aktiviert, richtig?
  • binäre Suche mit einigen a-priory Kenntnis der Verteilung werden die Daten noch schneller als die lineare Suche in den meisten Fällen; die einfachste ist die Verwendung der Abstände zu Linear interpoliert den splitting-Punkt für die nächste iteration statt in die Mitte der Reihe (das funktioniert am besten, wenn die Daten gleichmäßig verteilt, in anderen Fällen ist die interpolation Formel sollte ähnlich der Verteilung)
  • Wenn jemand Bestand auf der Verwendung einer linearen Suche auf sortierten Daten, ich möchte einfach nur wieder ein zufälliges Ergebnis, weil jemand so dumm wäre das nicht wissen, den Unterschied.
  • Nun, wenn Sie haben, um M sortiert Abfragen in ein array der N Elemente sortiert, die asymptotisch optimale algoirithm verläuft wie folgt: zunächst führen wir gegrätschten lineare Suche mit Schritt [N/M], d.h. lineare Suche überspringen, um jedes [N/M]-te element und führen Sie dann die binäre Suche in den gefundenen segment der Länge [N/M]. Wenn M in der Nähe N, [N/M] wird zu klein und die binäre Suche wird "deaktiviert". Also, keine binarey Suche, unter den oben genannten Bedingungen (d.h. ausreichend Dichte sortiert Abfragen der gleichen Daten) nicht schneller als eine lineare Suche. Lineare Suche sehr viel schneller.
  • Die obige Mischung aus gegrätschten-linear-Suche gefolgt von der binären Suche ist erwiesen, um asymptotisch optimalen Algorithmus erreicht das theoretische limit der Suche nach Effizienz. Also, keine binäre Suche ist nur schneller, wenn die Abfragen sind spärlich. Mit der dichten Abfragen, lineare Suche, gewinnt durch eine riesige Marge. Und, wieder, für die zwischen-Fällen, die der optimale Algorithmus verwendet die Mischung der beiden. Das theoretische Ergebnis ist von diesem Artikel: citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.22.5750
  • Die würde wahrscheinlich machen es viel mehr überraschend für Sie, um herauszufinden, dass inkrementelle lineare Suche auf sortierten Daten absolut Sinn macht, wenn wir haben, um mehrere sortiert Abfragen. Wenn die Anzahl der Abfragen Ansätze die Größe der Daten, lineare Suche als die binäre Suche um ein Vielfaches. Darüber hinaus werden aus diesem Grund praktisch jeder kann es benutzen (d.h. lineare Suche) beim mischen von sortierten Daten. Sie einfach nicht erkennen, dass.
  • dies ist nicht eine [code-golf] problem. Wenn es Links tagged wie, dass es geschlossen werden würde, weil die code-golf-Probleme, die nicht CW bekommen ständig geschlossen
  • Zusammenführen der sortierten Daten dauert lineare Zeit, aber es ist nicht eine lineare Suche. Sie sind richtig, über die Suche nach mehreren Werten auf einmal, aber das war nicht Teil der OP die Problematik.
  • Ja, es ist die lineare Suche 🙂 Die klassische merging-Algorithmus für sortierte arrays basiert auf der aktuellen minimales element aus dem array und sendet es zur Ausgabe. Es ist nicht offensichtlich, aber dies ist in der Tat nichts anderes als eine einfache lineare Suche eines elements von einem array in ein anderes array. Es ist einfach verschleiert ein wenig, so dass Sie nicht sehen es sofort, aber es Wirklichkeit ist es schlicht und unkompliziert lineare Suche.
  • Darüber hinaus ist die gleiche Logik gilt auch für die Zusammenführung so gut: wenn Sie das Zusammenführen von zwei arrays von deutlich unterschiedlicher Länge, es ist besser zu wechseln, um binäre Suche für die Zusammenführung aus. Aber wenn die Länge etwa gleich sind, nutzen wir die klassischen Algorithmus mit linearer Suche.
  • Ich bin nicht einverstanden, da die Listen sortiert sind, haben Sie die Zeiger auf die kleinste (oder größte) element im einzelnen, so sind Sie nie auf der Suche für das nächste element von einer der Teillisten, Sie sind nur zu entscheiden, welche Teilliste zu nehmen, das element aus.
  • Nein, Sie sind einfach das beharren auf eine bestimmte vision von dem, was passiert. Hier ist die althernative vision für Sie: zum ausführen der merge-wir nehmen das erste element a aus sortierten array A und führen Sie die lineare Suche nach element im sortierten array B. Das gibt uns eine [eventuell leer] Reihenfolge der führenden Elemente in B, die kleiner sind als a. Wir bewegen uns, die gesamte Sequenz zu Ausgabe, gefolgt von a. Dann wiederholen wir: nehmen Sie das nächste element a aus A... und so weiter. Das ist es.
  • Auf den ersten Blick klingt es vielleicht wie einen anderen Algorithmus, während, wenn Sie ein wenig darüber nachdenken, werden Sie sehen, dass dies genau der selben Klassiker-merging-Algorithmus, beschrieben nur in unterschiedliche Begriffe 🙂 Wieder, die klassische merging-Algorithmus ist nichts anderes als eine leicht verschleierte lineare Suche. Und wieder, wenn die arrays haben unterschiedliche Länge, die richtige Art und Weise zu tun, die Verschmelzung ist die Verwendung von binärer Suche: nehmen a aus A, binäre Suche in B verschieben Sie den Anfang der Sequenz von B Ausgabe, bewegen a Ausgabe, wiederholen.
  • Und wieder, der universal-asymptotisch optimale Strategie ist eine Mischung aus linearer und binärer Suche, wie beschrieben in meiner Antwort weiter unten.
  • Ich werde die Abstimmung zu schließen, ist diese Frage off-topic, weil es besser passt auf Code Überprüfen.
  • dies ist keine Frage für ein code-review der einfache Skalare lineare Suche, es ist mit das zu beschreiben/zeigen, dass der Algorithmus vektorisiert werden. Und außerdem, es ist zu alt, zu migrieren und die vorhandenen Antworten, also wenn das erste argument nicht überzeugen, dann würde ich noch vorschlagen, machen eine Ausnahme von der Regel für diese historische Frage.

InformationsquelleAutor Mark Probst | 2010-04-30
Schreibe einen Kommentar