Najlepsza odpowiedź
Nie jest jasne, o co pytasz, ale zakładam, że chodzi o to, że podana tablica , jak określasz jego długość.
C ma kilka typów tablic: tablice o nieznanym rozmiarze, tablice o znanym stałym rozmiarze i tablice o zmiennej długości.
Dla tablicy stały rozmiar, rozmiar jest częścią jego typu: długość tablicy o typie int[10]
jest równa 10. C nie ma mechanizmu wyodrębniania tego bezpośrednio z typu (w przeciwieństwie do C ++ ), ale możesz to zrobić pośrednio poprzez sizeof:
int a[] = {1,2,3,4,5,6,7,8,9,0};
size\_t sz = sizeof a / sizeof *a; // or .../sizeof a[0], same thing
printf("size = \%zu\n", sz);
Rozmiar tablicy o zmiennej długości można również obliczyć za pomocą sizeof, z identycznym kodem. W takim przypadku jest wykonywany w czasie wykonywania:
scanf("\%d", &x);
int a[x];
size\_t sz = sizeof a / sizeof *a;
printf("size = \%zu\n", sz);
Wreszcie, tablice o nieznanych granicach mają, z definicji nieznany rozmiar. Musiałbyś przejść przez logikę programu
extern int a[];
size\_t sz = something\_from\_the\_module\_that\_defines\_a();
Oczywiście jedno zastrzeżenie, nagie tablice w C nie mogą być przekazywane do funkcji, więc rozmiary muszą być obliczane po stronie wywołującego i przekazywane osobno:
void f(int *a, size\_t sz);
int a[] = {1,2,3,4,5,6,7,8,9,0};
f(a, sizeof a / sizeof *a);
tablice składowe można oczywiście przekazywać do funkcji według wartości:
struct a10 {int a[10];};
void f(struct a10 s) {
size\_t sz = sizeof s.a / sizeof *s.a;
}
Odpowiedź
Główne pytanie brzmi: czy będziesz wyszukiwać wiele razy? Jeśli tak, to zbuduj raz tablicę skrótów lub inny indeks, aby szybko znaleźć rzeczy. Tablicę skrótów można wygenerować w tym samym czasie, gdy dane są odczytywane z dysku (jeśli to stamtąd pochodzą).
Jeśli jest to jednorazowa operacja, a dane są ładowane z dysku, zrób wyszukiwanie pokrywało się z zamówieniem reklamowym. Można użyć 2 lub więcej buforów.
Kolejne pytanie brzmi: czy po prostu chcesz wiedzieć, czy coś jest obecne, czy też są powiązane dane, które chcesz odzyskać? Jeśli chcesz tylko wiedzieć, czy liczba jest obecna, możesz użyć tablicy bitowej, aby uzyskać bardziej zwartą reprezentację.
Poza tym, kod wbudowany w C z wykorzystaniem najszybszego porównania jest najlepszy; Użyj wszystkich opcji optymalizacji, które zapewnia Kompilator. Niektóre kompilatory mogą generować ten sam szybki kod, niezależnie od tego, czy używasz wskaźników, liczników czy indeksowania:
int * first = ..., * last = ...;
for ( ; first <= last; ++first ) if ( *first == target ) ...
lub
int * first = ..., count = ...;
for ( ; count-- > 0; ++first ) if ( *first == target ) ...
lub
int * first = ..., count = ..., index = ...;
for ( ; index < count; ++index ) if ( first[index] == target ) ...
Możesz uznać za oszustwo poproszenie kompilatora o wyjście kodu źródłowego asemblera w celu zorientowania się, co robi, ale mniejsze kompilatory mogą tego wymagać, jeśli naprawdę martwisz się o wydajność - tylko po to, aby zobaczyć, jaka forma kodu C generuje najlepszy wynik.
Są jeszcze inne rzeczy, które możesz zrobić, na przykład użycie wielu wątków: Jeśli masz dostępnych 8 rdzeni, możesz podzielić tablicę na 8 sekcji i uruchomić wątek dla każdej sekcji. Ale koszt uruchomienia wątków może być zbyt wysoki, jeśli koszt porównania jest niski.
Tablica może być duża, więc zamiana pamięci wirtualnej może spowolnić działanie. Korzystanie z własnych kopii zapasowych plików mapowanych w pamięci może pozwolić na kontrolowanie mapowania i usuwania mapowania w celu utrzymania niskiego zużycia pamięci fizycznej. Możesz usunąć mapowanie sekcji, którą właśnie skończyłeś, aby pamięć mogła zostać użyta dla późniejszych sekcji.
Tylko kilka pomysłów. Powodzenia.