Author: cazfi Date: Thu Nov 19 22:08:52 2015 New Revision: 30698 URL: http://svn.gna.org/viewcvs/freeciv?rev=30698&view=rev Log: Cache unit type vs unit type defense multiplier combat bonuses, and use those cached values instead of recalculating them every time they are needed.
See patch #6546 Modified: branches/S2_6/ai/default/advmilitary.c branches/S2_6/ai/default/aitech.c branches/S2_6/client/packhand.c branches/S2_6/common/combat.c branches/S2_6/common/unittype.c branches/S2_6/common/unittype.h branches/S2_6/server/ruleset.c Modified: branches/S2_6/ai/default/advmilitary.c URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_6/ai/default/advmilitary.c?rev=30698&r1=30697&r2=30698&view=diff ============================================================================== --- branches/S2_6/ai/default/advmilitary.c (original) +++ branches/S2_6/ai/default/advmilitary.c Thu Nov 19 22:08:52 2015 @@ -496,36 +496,24 @@ } unit_type_iterate_end; unit_list_iterate(ptile->units, punit) { - bool bonuses_exist = FALSE; struct unit_type *def = unit_type_get(punit); if (unit_has_type_flag(punit, UTYF_DIPLOMAT)) { city_data->has_diplomat = TRUE; } if (!defender_type_handled[utype_index(def)]) { - /* This is first defender of this type. Calculate defender type + /* This is first defender of this type. Check defender type * specific bonuses. */ - /* Vast majority of units have no Defense Multiplier bonus. - * Do not waste time on iterating through all unit types in the - * typical case by first checking if such bonuses exist against - * any units. */ - combat_bonus_list_iterate(def->bonuses, pbonus) { - if (pbonus->type == CBONUS_DEFENSE_MULTIPLIER) { - bonuses_exist = TRUE; - break; - } - } combat_bonus_list_iterate_end; - - if (bonuses_exist) { + /* Skip defenders that have no bonuses at all. Acceptable + * side-effect is that we can't consider negative bonuses at + * all ("No bonuses" should be better than "negative bonus") */ + if (def->cache.max_defense_mp > 0) { unit_type_iterate(utype) { - int bonus; int idx = utype_index(utype); - bonus = combat_bonus_against(def->bonuses, utype, - CBONUS_DEFENSE_MULTIPLIER); - if (bonus > defense_bonuses[idx]) { - defense_bonuses[idx] = bonus; + if (def->cache.defense_mp_bonuses[idx] > defense_bonuses[idx]) { + defense_bonuses[idx] = def->cache.defense_mp_bonuses[idx]; } } unit_type_iterate_end; } @@ -691,12 +679,7 @@ desire += punittype->move_rate / SINGLE_MOVE; desire += attack; - combat_bonus_list_iterate(punittype->bonuses, pbonus) { - if (pbonus->type == CBONUS_DEFENSE_MULTIPLIER - && pbonus->value > maxbonus) { - maxbonus = pbonus->value; - } - } combat_bonus_list_iterate_end; + maxbonus = punittype->cache.max_defense_mp; if (maxbonus > 1) { maxbonus = (maxbonus + 1) / 2; } @@ -704,6 +687,7 @@ if (utype_has_flag(punittype, UTYF_GAMELOSS)) { desire /= 10; /* but might actually be worth it */ } + return desire; } Modified: branches/S2_6/ai/default/aitech.c URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_6/ai/default/aitech.c?rev=30698&r1=30697&r2=30698&view=diff ============================================================================== --- branches/S2_6/ai/default/aitech.c (original) +++ branches/S2_6/ai/default/aitech.c Thu Nov 19 22:08:52 2015 @@ -373,9 +373,10 @@ struct advance *best_tech = A_NEVER; struct unit_type *best_unit = NULL; int def_values[U_LAST]; + int att_idx = utype_index(att); unit_type_iterate(deftype) { - int mp = combat_bonus_against(deftype->bonuses, att, CBONUS_DEFENSE_MULTIPLIER) + 1; + int mp = deftype->cache.defense_mp_bonuses[att_idx] + 1; int div = combat_bonus_against(att->bonuses, deftype, CBONUS_DEFENSE_DIVIDER) + 1; int def = deftype->defense_strength * mp / div; Modified: branches/S2_6/client/packhand.c URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_6/client/packhand.c?rev=30698&r1=30697&r2=30698&view=diff ============================================================================== --- branches/S2_6/client/packhand.c (original) +++ branches/S2_6/client/packhand.c Thu Nov 19 22:08:52 2015 @@ -3070,9 +3070,10 @@ road_integrators_cache_init(); /* Setup unit unknown move cost caches */ - unit_type_iterate(u) { - u->unknown_move_cost = utype_unknown_move_cost(u); - unit_type_action_cache_set(u); + unit_type_iterate(ptype) { + ptype->unknown_move_cost = utype_unknown_move_cost(ptype); + set_unit_type_caches(ptype); + unit_type_action_cache_set(ptype); } unit_type_iterate_end; /* We are not going to crop any more sprites from big sprites, free them. */ Modified: branches/S2_6/common/combat.c URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_6/common/combat.c?rev=30698&r1=30697&r2=30698&view=diff ============================================================================== --- branches/S2_6/common/combat.c (original) +++ branches/S2_6/common/combat.c Thu Nov 19 22:08:52 2015 @@ -515,8 +515,7 @@ if (NULL != att_type) { int defense_divider; - int defense_multiplier = 1 + combat_bonus_against(def_type->bonuses, att_type, - CBONUS_DEFENSE_MULTIPLIER); + int defense_multiplier = 1 + def_type->cache.defense_mp_bonuses[utype_index(att_type)]; defensepower *= defense_multiplier; @@ -747,6 +746,9 @@ /************************************************************************** Get bonus value against given unit type from bonus list. + + Consider using cached values instead of calling this recalculation + directly. **************************************************************************/ int combat_bonus_against(const struct combat_bonus_list *list, const struct unit_type *enemy, Modified: branches/S2_6/common/unittype.c URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_6/common/unittype.c?rev=30698&r1=30697&r2=30698&view=diff ============================================================================== --- branches/S2_6/common/unittype.c (original) +++ branches/S2_6/common/unittype.c Thu Nov 19 22:08:52 2015 @@ -29,6 +29,7 @@ /* common */ #include "ai.h" +#include "combat.h" #include "game.h" #include "government.h" #include "movement.h" @@ -1783,6 +1784,24 @@ unit_class_list_append(pclass->cache.subset_movers, pcharge); } } unit_class_iterate_end; +} + +/**************************************************************************** + Set caches for unit types. +****************************************************************************/ +void set_unit_type_caches(struct unit_type *ptype) +{ + ptype->cache.max_defense_mp = -FC_INFINITY; + + unit_type_iterate(utype) { + int idx = utype_index(utype); + + ptype->cache.defense_mp_bonuses[idx] = combat_bonus_against(ptype->bonuses, utype, + CBONUS_DEFENSE_MULTIPLIER); + if (ptype->cache.defense_mp_bonuses[idx] > ptype->cache.max_defense_mp) { + ptype->cache.max_defense_mp = ptype->cache.defense_mp_bonuses[idx]; + } + } unit_type_iterate_end; } /************************************************************************** Modified: branches/S2_6/common/unittype.h URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_6/common/unittype.h?rev=30698&r1=30697&r2=30698&view=diff ============================================================================== --- branches/S2_6/common/unittype.h (original) +++ branches/S2_6/common/unittype.h Thu Nov 19 22:08:52 2015 @@ -507,6 +507,13 @@ bool igwall; } adv; + struct { + int max_defense_mp; /* Value 0 here does not guarantee that unit never + * has CBONUS_DEFENSE_MULTIPLIER, it merely means + * that there's no POSITIVE one */ + int defense_mp_bonuses[U_LAST]; + } cache; + void *ais[FC_AI_LAST]; }; @@ -701,6 +708,7 @@ void unit_classes_free(void); void set_unit_class_caches(struct unit_class *pclass); +void set_unit_type_caches(struct unit_type *ptype); struct unit_class *unit_class_array_first(void); const struct unit_class *unit_class_array_last(void); Modified: branches/S2_6/server/ruleset.c URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_6/server/ruleset.c?rev=30698&r1=30697&r2=30698&view=diff ============================================================================== --- branches/S2_6/server/ruleset.c (original) +++ branches/S2_6/server/ruleset.c Thu Nov 19 22:08:52 2015 @@ -6994,8 +6994,9 @@ unit_class_iterate(pclass) { set_unit_class_caches(pclass); } unit_class_iterate_end; - unit_type_iterate(u) { - u->unknown_move_cost = utype_unknown_move_cost(u); + unit_type_iterate(ptype) { + ptype->unknown_move_cost = utype_unknown_move_cost(ptype); + set_unit_type_caches(ptype); } unit_type_iterate_end; /* Build advisors unit class cache corresponding to loaded rulesets */ _______________________________________________ Freeciv-commits mailing list Freeciv-commits@gna.org https://mail.gna.org/listinfo/freeciv-commits