+14
- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
#define MAX_MONSTER_ID 600
#define MAX_ITEM_FOR_MONSTER 40
for (int j=0; j < 1000; j++)
{
AllMobItemsDrop[j].MMap = 0;
AllMobItemsDrop[j].MMinLvl = 0;
AllMobItemsDrop[j].MMaxLvl = 0;
AllMobItemsDrop[j].IDropRate = 0;
AllMobItemsDrop[j].IGroup = 0;
AllMobItemsDrop[j].IIndex = 0;
AllMobItemsDrop[j].IMinLvl = 0;
AllMobItemsDrop[j].IMaxLvl = 0;
AllMobItemsDrop[j].ILvlRate = 0;
AllMobItemsDrop[j].IMinOpt = 0;
AllMobItemsDrop[j].IMaxOpt = 0;
AllMobItemsDrop[j].IOptRate = 0;
AllMobItemsDrop[j].ISkill = 0;
AllMobItemsDrop[j].ISkillRate = 0;
AllMobItemsDrop[j].ILuck = 0;
AllMobItemsDrop[j].ILuckRate = 0;
AllMobItemsDrop[j].IMinExc = 0;
AllMobItemsDrop[j].IMaxExc = 0;
AllMobItemsDrop[j].IExcRate = 0;
AllMobItemsDrop[j].IAnc = 0;
AllMobItemsDrop[j].IAncRate = 0;
}
AllMobArrayMaxItem = 0;
for (int i=0; i < MAX_MONSTER_ID; i++)
{
for (int j=0; j < MAX_ITEM_FOR_MONSTER; j++)
{
ItemsDrop[i][j].MMap = 0;
ItemsDrop[i][j].MMinLvl = 0;
ItemsDrop[i][j].MMaxLvl = 0;
ItemsDrop[i][j].IDropRate = 0;
ItemsDrop[i][j].IGroup = 0;
ItemsDrop[i][j].IIndex = 0;
ItemsDrop[i][j].IMinLvl = 0;
ItemsDrop[i][j].IMaxLvl = 0;
ItemsDrop[i][j].ILvlRate = 0;
ItemsDrop[i][j].IMinOpt = 0;
ItemsDrop[i][j].IMaxOpt = 0;
ItemsDrop[i][j].IOptRate = 0;
ItemsDrop[i][j].ISkill = 0;
ItemsDrop[i][j].ISkillRate = 0;
ItemsDrop[i][j].ILuck = 0;
ItemsDrop[i][j].ILuckRate = 0;
ItemsDrop[i][j].IMinExc = 0;
ItemsDrop[i][j].IMaxExc = 0;
ItemsDrop[i][j].IExcRate = 0;
ItemsDrop[i][j].IAnc = 0;
ItemsDrop[i][j].IAncRate = 0;
}
ArrayMaxItem[i] = 0;
}
Рабочий код с одного сервера. Код инициализации класа с заполнением структуры. А ведь это можно было уместить в:
memset(&AllMobItemsDrop, 0, sizeof(AllMobItemsDrop));
memset(&ItemsDrop, 0, sizeofe(ItemsDrop));
Запостил:
Killbrum,
31 Января 2013
struct sItemsDrop
{
short MMap; // #1
short MMinLvl; // #2
short MMaxLvl; // #3
short IDropRate; // #4
short IGroup; // #5
short IIndex; // #6
short IMinLvl; // #7
short IMaxLvl; // #8
short ILvlRate; // #9
short IMinOpt; // #10
short IMaxOpt; // #11
short IOptRate; // #12
short ISkill; // #13
short ISkillRate; // #14
short ILuck; // #15
short ILuckRate; // #16
short IMinExc; // #17
short IMaxExc; // #18
short IExcRate; // #19
short IAnc; // #20
short IAncRate; // #21
};
sItemsDrop ItemsDrop[MAX_MONSTER_ID][MAX_ITEM_FOR_MONSTER];
sItemsDrop AllMobItemsDrop[1000];
А memset в крестах лучше не юзать. Вот будут там потом какие-нибудь указатели или неPOD'ы, и будет вам море радости от мемсета.
P.S. А вместо дефайнов можно поюзать const int.
если бы мне попалась такая структура, регулярно требующая зануления (даже в методе clear), я бы написал memset в этом методе с комментом beware of ogres dirty hacks!
потому что кресты крестами, а структуру тому же программисту и поддерживать/расширять, который запарится с выявлением всех мест, где же еще надо дописывать строчки = 0 для новых полей
при желании можно всучить ассерт на is_pod, конечно
> который запарится с выявлением всех мест, где же еще надо дописывать строчки = 0 для новых полей
Вот в этом у жабы и паскаля есть плюс и минус по сравнению с крестами. Плюс - всегда понятно что по дефолту лежит в полях, и не надо всех этих мемсетов и занулений. Минус - оно, конечно же, медленнее.
есть обстоятельства?
Вместо
Для
и это всё заворачивать в метод
std::is_trivial и естественно std::is_pod экземпляры классов можно перемещать memmove и memcpy и занулять memset.
А std::is_standard_layout нахер нужен?
по нему можно делать грязные хаки с offsetof так, что это не приведет к UB
и => делать предположения насчет адреса его первого члена относительно адреса самого объекта
можно делать эти предположения, а в
уже нельзя?
trivial означает, что его инициализация тривиальна
ну а pod = trivial + standard layout
c++11 N3242 - 9.2.15
Nonstatic data members of a (non-union) class with the same access control (Clause 11) are allocated so that later members have higher addresses within a class object. The order of allocation of non-static data members with different access control is unspecified (11).
1) инициализация = конструктор класса (как минимум в данном коде).
2) кроме того куска там больше НИЧЕГО не было. Никаких выделений памяти и т.д.
3) сама структура статичная и имеет только 1 экземпляр
4) класс статичный и имеет только 1 экземпляр
5) код рабочий и сдан "в реализ". Но код сильно тормозит и грузит ЦПУ. Суть была оптимизировать код.
6) суть была в том что есть 3 цикла которые, фактически вручную, забивают нулями. Никто не пробовал посчитать тики процессора? Попробуйте сколько тиков на 3 цикла с 3мя временными переменными и сколько на простой мемсет
7) суть была в том что при добавлении данных в стуктуру надо бежать и дописывать вот такое вот зануливание. И так каждый раз.
8) суть была в том что вот эта хрень занимает лист А4 и видя такое в коде начинает хватать кондратий
P.S. жду минусов
Недождешься. Буду вести конструктивную беседу.
Написал небольшой бенчмарк - двойной цикл до 600 и до 40 и зануление 21 поля на каждой итерации (как в вашем нижнем цикле). И аналогичный бенчмарк для мемтеста того же самого массива. Результаты (10к итераций, gcc 4.6.3, амд 2ГГц) - мемсет 12.3с, циклы 27.3с. Разница всего в два раза.
> 3мя временными переменными
-O2, не, не слышал? Счетчики циклов чуть реже чем всегда попадают в регистры.
Говно тут не в очистке циклами, а архитектуре, из-за которой вообще возникла необходимость часто (если бы это было только при старте - на 2.7мс на довольно хреновом компе всем было бы похуй, и этот код бы тут не оказался) чистить большую структуру фиксированного размера (600х40 элементов).
> суть была в том что вот эта хрень занимает лист А4 и видя такое в коде начинает хватать кондратий
Есть такое. От срани с копипастом ItemsDrop[i][j] и AllMobItemsDrop[j] в каждой строке точно кондратий хватит.
Когда исходных данных не хватает - другого не остается.
Тики процессора сейчас неудобно считать, если это конечно не какой-нибудь атмеловский 8-битный контроллер. За счет спекулятивного исполнения и кешей все эти тики превращаются в ничего не значащее говно. Настоящее время исполнения можно оценить только досконально зная архитектуру конкретного проца (никто этого делать не будет, ибо долго и дорого), или прогнав прогу под профайлером.
Ну а вообще - спички-спичечки. Сделаем говно в архитектуре (типа необходимости частой очистки вон того массива 600х40), а потом будем выдрачивать производительность на спичках...
P.S. Под профайлером гоняли?
Вывод - ни циклы не мемсет не нужны. Вообще.
http://en.wikibooks.org/wiki/Ada_Programming/Generics
Совсем окрестился! Забудь эту мерзкую выкресть - "шаблоны".
Женерики, они же обобщения.
Так вот, шаблоны в Аде есть. А крестошаблонов - нет.
В Аде Generics - обобщения.
В С++ Templates - шаблоны.
А так адашаблоны, крестошаблоны, жабошаблоны, шарпошаблоны, хацкишаблоны - воистину КБГМ.
Просто не признает этого, опасается гонений.