2012-04-01 5 views
0

Gibt es eine schnelle Möglichkeit, die Anzahl der aufeinanderfolgenden Nullbytes ab einem bestimmten (char *) Zeiger in C zu zählen? Ich verwende derzeit eine Tight-Loop, die gut funktioniert und schnell genug ist, aber die String-Funktionen von libc/gcc sind in der Regel noch schneller.Wie zähle ich aufeinanderfolgende null ( 0) Bytes in C?

Ich bin auf der Suche nach etwas ähnlich strspn, buf strspn (natürlich) stoppt bei der ersten Null-Byte und ist daher für diese Aufgabe nutzlos. Ich denke, Sie könnten auch sagen, ich bin auf der Suche nach der Umkehrung von strlen, die Anzahl der Bytes zurückgibt, die nicht null sind.

+5

Wenn das NUL-Byte nicht das Ende der Zeichenfolge ist, woher wissen Sie dann, wo die Zeichenfolge endet? – delnan

+5

Wenn es schnell genug ist ... warum Botter ?! – Anthales

+2

Es gibt wahrscheinlich einige handgeschriebene Assembler in der C-Bibliothek Implementierung. Sie können bis zum nächsten ausgerichteten Zeiger vorrücken und beginnen, ganzzahlige Werte zu vergleichen. –

Antwort

2

nicht verfügbar Speicher erreicht Wenn Ihr Zeigerwort ausgerichtet ist, können Sie es für zeroness ein Wort zu einem Zeitpunkt überprüfen können.

int zeros(char *p) 
{ 
    int n = 0; 
    if ((int)p & 1) { 
    if (*p) 
     return 0; 
    p++; 
    n++; 
    } 
    if ((int)p & 2) { 
    if (*(short *)p) 
     goto label1; 
    p += 2; 
    n += 2; 
    } 
    if ((int)p & 4) { 
    if (*(long *)p) 
     goto label2; 
    p += 4; 
    n += 4; 
    } 
    while (!*(long long *)p) { 
    p += 8; 
    n += 8; 
    } 
    if (!*(long *)p) { 
    p += 4; 
    n += 4; 
    } 
label2: 
    if (!*(short *)p) { 
    p += 2; 
    n += 2; 
    } 
label1: 
    if (!*p) 
    n++; 
    return n; 
} 
+0

Schöne Idee, aber ich bin unruhig über die Annahme, dass ein Int ist 4 Zeichen lang, etc. –

+0

"Int" ist nicht garantiert, groß genug, um einen Zeiger Wert zu halten. Verwenden Sie '(u) intptr_t' aus' stdint.h' oder, falls nicht verfügbar, 'size_t'. –

+0

@KyleJones: Sie können 'sizeof()' verwenden, um die Schriftgröße zu überprüfen. Sie können auch [compile-time "assert"] (http://www.flipcode.com/archives/Compile-Time_Asserts.shtml) verwenden, um sicherzustellen, dass Ihr Code nicht auf Plattformen kompiliert wird, deren Größe sich unterscheidet. –

3

Ich weiß nicht, ob ein solches Verfahren vorhanden ist, aber wenn Sie es selbst schreiben, könnten Sie die Sätze von 4 oder 8 Bytes zusammen, unter Verwendung eines (int*) oder eine (long*) überprüfen.

+0

das ist eine gute Idee, aber am Ende müssen Sie messen. Und sehr oft entdeckt die einfachste Lösung, dass sie schneller ist. (Ich erinnere mich, dass ich überrascht war, dass der Java Jit Compiler acht Wiederholungen in Serie durchführt, um Inkremente zu speichern, mit dem Ergebnis, dass Jit die Schleife langsamer macht :-() –

+0

Es gibt keine starke Korrelation zwischen der Komplexität eines Codes und seiner Effizienz Größe und Komplexität sind nicht gleich – Vincent

2

Was ist damit?

char* start = ... 
char* act = start; 
while (*act++ == 0); 
ptrdiff_t nulls = (act - start) - 1; 

sollte jedoch etwas garantieren die während zu stoppen, bevor es

+1

'ptrdiff_t' oder' size_t' aber nicht 'int' –

+0

Dies ist im Wesentlichen die enge Schleife, die ich gerade benutze.Thanks though :) –

2

Es ist kein schneller Weg, dies in tragbaren, Standard C.

Der C-Compiler builtins und Standard-Bibliothek tun schneller gehen können, weil sie in tragbaren nicht geschrieben werden müssen, Standard C - sie können das umsetzungsspezifische Wissen nutzen.

Sie könnten diesen Weg natürlich selbst gehen - aber wenn das, was Sie haben, bereits schnell genug ist, ist es dann wirklich die Portabilität und Wartbarkeitskosten wert?

Verwandte Themen