ECS? Właściwie zasugeruję, że może to nie być przedwczesne, jeśli tak, aby przemyśleć stronę projektu zorientowaną na dane i porównać różne powtórzenia, ponieważ może to wpłynąć na projekty interfejsów , a ta ostatnia jest bardzo kosztowna, aby zmienić ją późno gra. Również ECS wymaga dużo pracy i przemyślenia z wyprzedzeniem i myślę, że warto poświęcić trochę tego czasu, aby upewnić się, że nie przyniesie ci to żalu wydajności na poziomie projektowym, biorąc pod uwagę, jak będzie w sercu twojego cały cholerny silnik. Ta część rzuca mi spojrzenie:
unordered_map<string,[yada]>
Nawet przy małych optymalizacjach ciągów kontener o zmiennej wielkości (łańcuchy) znajduje się w innym kontenerze o zmiennej wielkości (unordered_maps). W rzeczywistości, małe optymalizacje strunowe faktycznie mogła być równie szkodliwe jak pomocne w tym przypadku, jeśli stół jest bardzo rzadki, ponieważ małe optymalizacja ciąg oznaczałoby, że każdy niewykorzystany indeks tabeli mieszania będzie nadal korzystać z większej ilości pamięci dla optymalizacji SS ( sizeof(string)będzie być znacznie większy) do tego stopnia, że całkowity narzut pamięci w tabeli skrótów może kosztować więcej niż cokolwiek, co jest w niej przechowywane, szczególnie jeśli jest to prosty komponent, taki jak element pozycji, oprócz ponoszenia większej ilości braków w pamięci podręcznej z ogromnym krokiem aby przejść od jednego wpisu w tabeli skrótów do następnego.
Zakładam, że ciąg jest jakimś kluczem, takim jak identyfikator komponentu. Jeśli tak, to już czyni rzeczy znacznie tańszymi:
unordered_map<int,[yada]>
... jeśli chcesz mieć korzyści z posiadania przyjaznych dla użytkownika nazw, których mogą używać skrypty, np. wtedy wewnętrzne łańcuchy mogą dać ci to, co najlepsze z obu światów.
To powiedziawszy, jeśli możesz odwzorować ciąg na stosunkowo niski zakres gęsto używanych wskaźników, możesz po prostu być w stanie to zrobić:
vector<[yada]> // the index and key become one and the same
Powodem, dla którego nie uważam tego przedwczesnego, jest to, że znowu może to wpłynąć na projekty interfejsów. Celem DOD nie powinna być próba wymyślenia najbardziej wydajnych reprezentacji danych możliwych do wyobrażenia za jednym razem IMO (które ogólnie powinny być osiągane iteracyjnie w razie potrzeby), ale przemyślenie ich na tyle, aby zaprojektować interfejsy do pracy z tym dane, które zapewniają wystarczającą swobodę oddechu do profilowania i optymalizacji bez kaskadowych zmian w projekcie.
Naiwnym przykładem jest oprogramowanie do przetwarzania wideo, które łączy cały swój kod z tym:
// Abstract pixel that could be concretely represented by
// RGB, BGR, RGBA, BGRA, 1-bit channels, 8-bit channels,
// 16-bit channels, 32-bit channels, grayscale, monochrome,
// etc. pixels.
class IPixel
{
public:
virtual ~IPixel() {}
...
};
Nie zajdzie daleko bez potencjalnie epickiego przepisywania, ponieważ pomysł abstrakcji na poziomie pojedynczego piksela jest już niezwykle nieefektywny ( vptrsam kosztowałby często więcej pamięci niż cały piksel) w porównaniu do abstrakcji na poziomie obrazu (który będzie często reprezentują miliony pikseli). Dlatego z góry zastanów się nad przedstawieniami danych, abyś nie musiał stawić czoła takiemu koszmarnemu scenariuszowi, a najlepiej nie więcej, ale myślę, że warto o tym pomyśleć z góry, ponieważ nie chcesz budować skomplikowany silnik wokół ECS i przekonaj się, że sam ECS stanowi wąskie gardło w zakresie, który wymaga zmiany rzeczy na poziomie projektu.
Jeśli chodzi o pomyłki w pamięci podręcznej ECS, moim zdaniem programiści często starają się, aby ich ECS był przyjazny dla pamięci podręcznej. Zaczyna dawać zbyt mały huk, aby złotówka próbowała uzyskać dostęp do wszystkich komponentów w idealnie ciągły sposób, i często oznacza kopiowanie i tasowanie danych w dowolnym miejscu. Zwykle wystarczy, powiedzmy, po prostu posortować indeksy składników sortowania przed uzyskaniem dostępu do nich, aby uzyskać do nich dostęp w sposób, w którym przynajmniej nie ładujesz obszaru pamięci do linii pamięci podręcznej, tylko aby go eksmitować, a następnie załadować wszystko od nowa w tej samej pętli, aby uzyskać dostęp do innej części tej samej linii pamięci podręcznej. I ECS nie musi zapewniać niesamowitej wydajności na całym pokładzie. To nie jest tak, że system wejściowy czerpie z tego tyle korzyści, co fizyka lub system renderowania, więc zalecam dążenie do „dobrego” ogólna wydajność i „doskonała” w miejscach, w których naprawdę jej potrzebujesz. To powiedziawszy, użyjunordered_mapi stringtutaj są wystarczająco łatwe do uniknięcia.