To, przed czym stoisz, to klasyczny kompromis między czasem a pamięcią. Pola bitowe będą mniejsze w pamięci, ale operacja na nich zajmie więcej czasu. Możesz policzyć, że bez względu na procesor, pola bitowe będą wolniejsze.
Używasz słowa wydajne , ale słowo to nie ma określonego znaczenia bez miernika tego, co jest dobre lub zły. Gdy masz tylko 8 kB RAM, używanie pamięci jest złe, czas może być tani. Jeśli masz ograniczenia czasu rzeczywistego, używanie czasu jest złe, a pamięć może być tania. Ogólnie rzecz biorąc, możesz wykupić tylko wyjście z tego kompromisu. Innymi słowy, jeśli uznasz, że zarówno czas, jak i pamięć są złe, wydaj gotówkę i użyj większego chipa. Nie ma jednej odpowiedzi na to, co jest dobre, a co złe. To jest jeden z powodów, dla których mikrokontrolery mają tak duży wybór, że ludzie dopasowują chip do aplikacji, a aplikację do chipa.
Wypełnianie bitów pola bitowego będzie wolniejsze niż wypełnianie całych bajtów. Weźmy na przykład
x = 5; ... asimplestruct.len = x; // vsabitfield.len = x;
Pierwszy prosty przypadek będzie po prostu:
- załaduj wartość x do rejestru
- zapisz ją do bajtu dla len
Druga robi coś takiego:
- ładuje aktualną wartość abitfield
- ładuje maskę
- czyści bity dla len
- ładuje aktualną wartość x
- wczytuje maskę
- usuwa nieużywane bity x
- przesuwa bity x
- lub x z polem abitfield
- zapisuje bieżącą wartość z powrotem w pamięci
Jeśli wszystkie twoje operacje pakują dane do pola bitowego lub wypakowują je z pola bitowego, powinieneś spodziewać się wolniejszego wykonania. Pola bitowe są rodzajem kompresji - kosztują takty.
Ale poruszanie się po polach bitowych będzie szybsze, ponieważ jest mniej bajtów do załadowania i przechowywania. Jeśli sortujesz tę tablicę, mniejsza liczba bajtów może być zaletą. Jeśli przenosisz je przez port szeregowy, skompresowany rozmiar pola bitowego może być zwycięzcą.
W odniesieniu do twojego pytania:
Czy istnieje dobry sposób, aby to przetestować?
Jedynym dobrym sposobem na sprawdzenie tego jest napisanie przypadki testowe dla obu podejść przy użyciu wzorca, który ściśle pasuje do Twojej aplikacji. Naprawdę ważne jest, jaką kombinację operacji wykonasz, aby zdecydować, czy różnica jest nieistotna czy znacząca.
Podczas tego rodzaju eksperymentu optymalizacyjnego zdecydowanie użyj kontroli źródła w swoim projekcie. Możesz utworzyć lokalne repozytorium GIT lub Mercurial za pomocą kilku kliknięć. Utrzymanie łańcucha punktów kontrolnych pozwala na rozerwanie kodu, badając skutki różnych implementacji. Jeśli skręcisz w złą stronę, repozytorium pozwoli ci po prostu wrócić do ostatniego dobrego punktu i wypróbować inną ścieżkę.
(Uwaga dodatkowa: tym razem wymiana pamięci istnieje również w przeciwnym kierunku. Jeśli spojrzysz poprzez opcje kompilatora dla procesorów klas dla komputerów stacjonarnych znajdziesz coś, co nazywa się pakowaniem struktury . Ta opcja pozwala na dodanie pustych bajtów między polami jednobajtowymi, tak aby pozostały wyrównane na granicach słowa lub podwójnego słowa. celowe wyrzucanie pamięci RAM wydaje się szalone, ale w procesorach z rejestrami i magistralami o szerokości 16 lub 32 bitów tak zwane operacje pamięciowe wyrównane słowem lub dwordami mogą być szybsze niż operacje na bajtach).