Несколько советов:
а) пример кода слишком мал, чтобы иметь значение
b) никогда не используйте malloc()
для чего-то, что вы всегда захотите. Вместо этого предварительно выделите (например, как глобальную переменную) или (если она достаточно мала) используйте локальную переменную, чтобы избежать издержек malloc()
. E.g.:
int main(void) {
struct Player test, *p = &test;
char userName[50];
p->username = userName;
в) Не распространяйте данные повсюду. Вы хотите, чтобы все данные находились в одном и том же месте (в наименьшем количестве строк кэша, с частями данных, которые используются в одно и то же время как можно ближе друг к другу). Один из способов сделать это - объединить несколько предметов. E.g.:
struct Player {
char username[50];
int hp;
int mp;
};
int main(void) {
struct Player test, *p = &test;
d) Если что-то занимает (максимум) 50 символов памяти; не тратьте время на использование realloc()
, чтобы тратить впустую процессорное время и потенциально тратить больше памяти. Не забывайте, что внутренний код для malloc()
и realloc()
добавит метаданные к каждому выделенному фрагменту памяти, который, вероятно, будет стоить дополнительно 16 байтов или более.
В общем; для производительности следует полностью избегать malloc()
и realloc()
(и new()
и ...) (особенно для более крупных программ). Они распространяют данные «случайным образом» повсюду и разрушают любую надежду на получение хорошей локализации (что важно для минимизации множества очень дорогих вещей - кеш-пропусков, пропусков TLB, сбоев страниц, использования пространства подкачки, ...).
Примечание: scanf()
и gets()
также должны быть запрещены. Они не позволяют предотвратить переполнение буфера (например, пользователь предоставляет более 50 символов, когда для 50 символов выделено только достаточно памяти для преднамеренной очистки / повреждения других данных), что приводит к огромным дырам в безопасности.