Array (bool) komfortabel vergleichen auf alles true

milamber

Grünschnabel
Moin,
gibt es eine komfortable und schnelle (= möglichst wenig Takte nötig) Möglichkeit zu testen, ob alle Elemente eines booleschen Arrays auf true bzw false stehen?
Oder ist eine for-schleife über das Array das schnellstmögliche?

Eine alternative Idee die mir dazu einfällt am konkreten Beispiel:
bool test[4]; // je element 1 byte = insgesamt 4 byte
int tester; //int 32bit = 4 byte
tester = test; //liest der jetzt die 4 byte des arrays in das integer ein?
if(tester == 0x0000)
printf("alles false");
if(tester == 0x1111)
printf("alles true");

Ich hab momentan leider keine Möglichkeit zur Hand, um diese Idee eben auszuprobieren.

Gruß,
Bodo
 
Hi.

Hast du denn eigentlich ein Problem mit der Geschwindigkeit beim Testen ob alles 0 bzw. 1 ist? Wenn nicht, solltest du dich nicht unbedingt daran herumoptimieren wenn es dafür keinen Grund gibt und du (vermutlich) noch nicht mal getestet hast, ob der Compiler deinen Code dafür nicht bereits automatisch optimieren kann.

Dann kommt es darauf an ob du ein statisches oder ein dynamisches Array hast. Bei einem statischen Array hat der Compiler die Möglichkeit eine Schleife aufzulösen (Option bei GCC -funroll-loops).

Das kann man aber auch für dynamische Array per Hand bewerkstelligen:
C:
#include<stdio.h> 

#define BLOCKSIZE (8) 

int main(void)
{ 
int i = 0; 
int limit = 33;  /* could be anything */ 
int blocklimit; 

/* The limit may not be divisible by BLOCKSIZE, 
 * go as near as we can first, then tidy up.
 */ 
blocklimit = (limit / BLOCKSIZE) * BLOCKSIZE; 

/* unroll the loop in blocks of 8 */ 
while( i < blocklimit ) 
{ 
    printf("process(%d)\n", i); 
    printf("process(%d)\n", i+1); 
    printf("process(%d)\n", i+2); 
    printf("process(%d)\n", i+3); 
    printf("process(%d)\n", i+4); 
    printf("process(%d)\n", i+5); 
    printf("process(%d)\n", i+6); 
    printf("process(%d)\n", i+7); 

    /* update the counter */ 
    i += 8; 
}
/* 
 * There may be some left to do.
 * This could be done as a simple for() loop, 
 * but a switch is faster (and more interesting) 
 */ 

if( i < limit ) 
{ 
    /* Jump into the case at the place that will allow
     * us to finish off the appropriate number of items. 
     */ 

    switch( limit - i ) 
    { 
        case 7 : printf("process(%d)\n", i); i++; 
        case 6 : printf("process(%d)\n", i); i++; 
        case 5 : printf("process(%d)\n", i); i++; 
        case 4 : printf("process(%d)\n", i); i++; 
        case 3 : printf("process(%d)\n", i); i++; 
        case 2 : printf("process(%d)\n", i); i++; 
        case 1 : printf("process(%d)\n", i); 
    }
} 
return 0;
}
Die Verarbeitung des Arrays findet hier in 8ter Blöcken statt, nicht einzeln. Somit wird nicht für jeden Funktionsaufruf die Variable i inkrementiert und getestet - was im Normalfall dazu führt, das die Ausführung beschleunigt wird.

Generell ist es auch keine schlechte Idee statt byteweise vorzugehen wie du schon vorgeschlagen hast, gleich die max. Zahl an Bytes die ein Register fassen kann zu testen. Du könntest natürlich die Methoden kombinieren. Aber: Premature optimization is the root of all evil.

Gruß
 
Das kann so nicht klappen!

1. Die Zuweisung von bool-Array nach int geht nicht
2. Ein bool hat nicht notwendigerweise 1 Byte Größe. Ich glaube, das ist nicht festgelegt, aber die meisten Compiler realisieren ein bool als int.

Du kannst es natürlich mit einer Schleife machen, die alle Arrayelemente durchläuft. Das wäre am sichersten, auch vom Datentyp her. Ein boole'sches true heißt nämlich nicht 'Wert 1' sondern 'Wert != 0'

Du kannst allerdings auch die STL-Klasse 'bitset' verwenden, da gibt es ähnliche Funktionen schon.
 
Hallo,

2. Ein bool hat nicht notwendigerweise 1 Byte Größe. Ich glaube, das ist nicht festgelegt, aber die meisten Compiler realisieren ein bool als int.
Kann ich mir ehrlich gesagt nicht vorstellen. Vom GCC-Compiler weiß ich zumindest, dass ein bool genau ein Byte belegt (sizeof(bool)). Wieso sollte man auch 4 Bytes für eine 1-Bit-Information verschwenden?

Ein boole'sches true heißt nämlich nicht 'Wert 1' sondern 'Wert != 0'
Jein… beim Umwandeln eines Zahlenwertes in einen Wahrheitswert wird die 0 zum false, alles andere wird true. In die andere Richtung ergibt ein false immer 0, ein true immer 1. Zumindest handhaben alle von mir verwendeten Compiler es so.

@milamber: Was du willst, ist vermutlich dieses:
C++:
#include <iostream>

int main()
{
    bool flags[4];
    flags[0] = flags[1] = flags[2] = flags[3] = true;
    int fourflags = *reinterpret_cast<int *>(flags);

    if (fourflags == 0x00000000) {
        std::cout << "Alles false";
    } else if (fourflags == 0x01010101) {
        std::cout << "Alles true";
    }
}
Aber ob das jetzt so viel schneller ist…

Grüße,
Matthias
 
Moin,
also zumindest beim VC++ belegt ein bool auch nur ein byte.
Die Lösung von Matthias mit dem reinterpret_cast<int *> habe ich jetzt übernommen. Die belegt für diesen cast nur 2 Assembleranweisungen (MOV mit ptr-auflösung), die Vergleiche danach ein einzeiliges CMP (mit ptr-auflösung).

Ich wollte diese Vergleiche optimieren, da sie in der Auswertung eines automatisierten Tests in einer Schleife über alle Nachrichten immer wieder aufgerufen werden. Das können schnell mal 30.000 Nachrichten pro Datei werden.

Dieses reinterpret_cast Template kannte ich noch nicht, wieder etwas gelernt. Wenn man nicht weiß, wonach man exakt suchen muß, findet man so etwas ja auch nicht.

Danke.

Gruß,
Bodo
 
Zurück