def dump_object_scores(_connection=None):
    object_scores = defaultdict(Counter)
    (on_lot_objects, off_lot_objects) = _score_all_objects(object_scores)

    def _score_objects_callback(file, verbose=False):
        file.write('Object,total,On Lot,Off Lot')
        if verbose:
            file.write(
                ',Interaction,Autonomous,provided posture,state component,client change tuning,parts,stats,commodities,portal,inventory item, inventory, Object, Time Spent Adding, Time Spent Loading, Adds, Loads, Avg Load Time\n'
            )
        else:
            file.write('\n')
        for object_type in object_scores:
            _dump_object_to_file(object_type,
                                 object_scores,
                                 on_lot_objects,
                                 off_lot_objects,
                                 file,
                                 verbose=verbose)
        _dump_total_score(object_scores, on_lot_objects, off_lot_objects, file)

    create_csv(
        'object_scores_verbose',
        lambda new_file: _score_objects_callback(new_file, verbose=True),
        _connection)
    create_csv('object_scores_simple', _score_objects_callback, _connection)
def dump_tests_profile(sort:SortStyle=SortStyle.AVERAGE_TIME, _connection=None):
    output = sims4.commands.CheatOutput(_connection)
    if event_testing.resolver.test_profile is None:
        output('Test profiling is currently disabled. Use |performance.test_profile.enable')
        return
    if len(event_testing.resolver.test_profile) == 0:
        output('Test profiling is currently enabled but has no records.')
        return

    def sort_style(metric):
        if sort == SortStyle.AVERAGE_TIME:
            return metric.average_time
        if sort == SortStyle.TOTAL_TIME:
            return metric.total_time
        return metric.count

    def callback(file):
        TIME_MULTIPLIER = 1000
        file.write('Test,Count,AverageTime(ms),TotalTime(ms),Resolver,Key,Count,AverageTime(ms),TotalTime(ms)\n')
        for (test_name, test_metrics) in sorted(event_testing.resolver.test_profile.items(), key=lambda t: sort_style(t[1].metrics), reverse=True):
            file.write('{},{},{},{},,,,,\n'.format(test_name, test_metrics.metrics.count, test_metrics.metrics.average_time*TIME_MULTIPLIER, test_metrics.metrics.total_time*TIME_MULTIPLIER))
            for resolver in sorted(test_metrics.resolvers.keys()):
                data = test_metrics.resolvers[resolver]
                for (key, metrics) in sorted(data.items(), key=lambda t: sort_style(t[1]), reverse=True):
                    while metrics.average_time > 0:
                        file.write(',,,,{},{},{},{},{}\n'.format(resolver, key, metrics.count, metrics.average_time*TIME_MULTIPLIER, metrics.total_time*TIME_MULTIPLIER))

    create_csv('test_profile', callback=callback, connection=_connection)
Esempio n. 3
0
def mem_garbage_dump(_connection=None):
    old_flags = gc.get_debug()
    gc.set_debug(gc.DEBUG_SAVEALL)
    gc.collect()

    def write_to_file(file):
        garbage_ids = set(id(i) for i in gc.garbage)
        for o in gc.garbage:
            referents = tuple(r for r in gc.get_referents(o)
                              if id(r) in garbage_ids)
            try:
                orepr = repr(o)
            except:
                orepr = '<exc>'
            file.write('{};{};{}{};{}\n'.format(
                len(referents), id(o),
                ''.join('{};'.format(id(r)) for r in referents),
                type(o).__name__, orepr))

    output = sims4.commands.CheatOutput(_connection)
    output('Garbage count: {}'.format(len(gc.garbage)))
    filename = 'garbage_graph'
    create_csv(filename, callback=write_to_file, connection=_connection)
    gc.garbage.clear()
    gc.set_debug(old_flags)
Esempio n. 4
0
def print_exclusivity_options(_connection=None):
    def callback(file):
        file.write('Category,' +
                   ','.join(cat.name
                            for cat in BouncerExclusivityCategory) + '\n')
        for cat1 in BouncerExclusivityCategory:
            row = [cat1.name]
            for cat2 in BouncerExclusivityCategory:
                rule = Bouncer.are_mutually_exclusive(cat1, cat2)
                if rule is None:
                    row.append('')
                elif rule[2] == BouncerExclusivityOption.NONE:
                    row.append('<' if rule[0] == cat1 else '^')
                elif rule[
                        2] == BouncerExclusivityOption.EXPECTATION_PREFERENCE:
                    row.append('EP')
                elif rule[2] == BouncerExclusivityOption.ALREADY_ASSIGNED:
                    row.append('AR')
                else:
                    row.append('ERROR')
            file.write(','.join(row) + '\n')
        file.write('\n\n')
        file.write('Legend:')
        file.write(',<,left category trumps above category\n')
        file.write(',^,above category trumps left category\n')
        file.write(',EP,expectation preference\n')
        file.write(',AR,already assigned\n')
        file.write(',blank,coexist\n')

    create_csv('bouncer_exclusivity_options',
               callback=callback,
               connection=_connection)
def dump_object_load_times(_connection=None):
    if not indexed_manager.capture_load_times:
        return False

    def _object_load_time_callback(file):
        file.write('Object,AddTime,LoadTime,Adds,Loads\n')
        for (object_class, object_load_data) in object_load_times.items():
            if not isinstance(object_class, str):
                file.write('{},{},{},{},{},{}\n'.format(
                    object_class, object_load_data.time_spent_adding,
                    object_load_data.time_spent_loading, object_load_data.adds,
                    object_load_data.loads,
                    (object_load_data.time_spent_adding +
                     object_load_data.time_spent_loading) /
                    object_load_data.adds
                    if object_load_data.adds > 0 else '0'))
        time_adding = sum([
            y.time_spent_adding for (x, y) in object_load_times.items()
            if not isinstance(x, str)
        ])
        time_loading = sum([
            y.time_spent_loading for (x, y) in object_load_times.items()
            if not isinstance(x, str)
        ])
        file.write(',{},{}\n'.format(time_adding, time_loading))
        if 'household' in object_load_times:
            file.write('Household,{}\n'.format(object_load_times['household']))
        file.write('Posture Graph,{},'.format(
            object_load_times['posture_graph']))
        file.write('Lot Load,{}\n'.format(object_load_times['lot_load']))

    create_csv('object_load_times', _object_load_time_callback, _connection)
def autonomy_distance_estimates_log_file(_connection=None):
    affordance_times = autonomy.autonomy_modes.g_affordance_times
    if affordance_times is None:
        return

    def callback(file):
        for (delta, count, _, affordance) in reversed(sorted([(delta, count, id(affordance), affordance) for (affordance, (count, delta)) in affordance_times.items()])):
            file.write('{},{},{}\n'.format(affordance, count, delta))

    create_csv('autonomy_distance_estimate_times', callback=callback, connection=_connection)
Esempio n. 7
0
def gather_tick_metrics_stop(_connection=None):

    def callback(file):
        zone = services.current_zone()
        tick_data = zone.tick_data
        zone.stop_gathering_tick_metrics()
        file.write('ABSOLUTE TICKS,SIM NOW READABLE, SIM NOW TICKS,CLOCK SPEED ENUM,CLOCK SPEED MULTIPLIER,GAME TIME READABLE,GAME TIME TICKS,MULTIPLIER TYPE\n')
        for data in tick_data:
            file.write('{},{},{},{},{},{},{},{}\n'.format(data.absolute_ticks, data.sim_now, data.sim_now.absolute_ticks(), data.clock_speed, data.clock_speed_multiplier, data.game_time, data.game_time.absolute_ticks(), data.multiplier_type))

    create_csv('tick_metrics', callback=callback, connection=_connection)
 def create_interaction_view():
     for (tname, tmetrics) in event_testing.resolver.test_profile.items():
         interaction_resolver = tmetrics.resolvers.get(
             'InteractionResolver')
         if interaction_resolver is None:
             continue
         for (interaction, metrics) in interaction_resolver.items():
             interactions[interaction].append((tname, metrics))
     filename = 'test_profile_interactions'
     create_csv(filename,
                callback=interaction_callback,
                connection=_connection)
Esempio n. 9
0
def analyze_slots(verbose:bool=False, _connection=None):
    output = sims4.commands.CheatOutput(_connection)
    if verbose:
        output('Collecting GC')
    gc.collect()
    if verbose:
        output('Gathering objects')
    pending = collections.deque(gc.get_objects())
    all_objects = {id(obj): obj for obj in pending}
    while pending:
        obj = pending.pop()
        referents = gc.get_referents(obj)
        for child in referents:
            if id(child) not in all_objects:
                all_objects[id(child)] = child
                pending.append(child)
                if verbose and not len(all_objects) % 1000000:
                    output('...{} pending: {}'.format(len(all_objects), len(pending)))
    if verbose:
        output('Collating types')
    type_map = collections.defaultdict(list)
    for obj in all_objects.values():
        tp = type(obj)
        type_map[tp.__module__ + '.' + tp.__qualname__].append(obj)
    del all_objects

    def write_to_file(file):
        file.write('Type,Count,Size,Each,SlotSize,SlotEach,Attribs,SlotSavings,SlotSavings(MB),__slots__\n')
        for type_name in sorted(type_map.keys()):
            objects = type_map[type_name]
            if not hasattr(objects[0], '__dict__'):
                continue
            size = 0
            attribs = set()
            if isinstance(objects[0], tuple):
                for obj in objects:
                    attribs |= set(str(name) for name in vars(obj))
                    size += sys.getsizeof(obj)
            else:
                for obj in objects:
                    attribs |= set(str(name) for name in vars(obj))
                    size += sys.getsizeof(obj) + sys.getsizeof(obj.__dict__)
            inst_size = size/len(objects)
            slot_inst_size = _size_of_slots(len(attribs))
            slot_size = slot_inst_size*len(objects)
            slot_savings = size - slot_size
            slots_string = str(tuple(attribs)).replace(',', '') if len(attribs) < 50 else '(...)'
            file.write('{},{},{},{:0.2f},{},{},{},{},{:0.2f},{}\n'.format(type_name, len(objects), size, inst_size, slot_size, slot_inst_size, len(attribs), slot_savings, slot_savings/1048576, slots_string))

    filename = 'PyOpt_AnalyzeSlots'
    create_csv(filename, callback=write_to_file, connection=_connection)
Esempio n. 10
0
def object_count_log_dump(_connection=None):
    output = sims4.commands.CheatOutput(_connection)
    if gc_object_counts is None:
        output(
            'Object count logging is disabled. Enable with |mem.gc.object_count_log_start'
        )
        return

    def callback(file):
        file.write('minutes,count,collected\n')
        for (count, timestamp, collected) in gc_object_counts:
            file.write('{},{},{}\n'.format(timestamp, count, collected))

    create_csv('gc_object_counts', callback=callback, connection=_connection)
Esempio n. 11
0
    def dump(cls, connection=None):
        if cls._affordance_times is None:
            return
        affordance_times = cls._affordance_times._affordances
        if not affordance_times:
            return

        def callback(file):
            file.write('Interaction,Count,TotalTime(s),AvgTime(s),TotalDistTime(s),AvgDistTime(s),TotalTransitionTime(s),AvgTransitionTime(s),TotalCompatTime(s),AvgCompatTime(s), Dist %, Transition %, Compat %\n')
            affordances = [(total, dist, transition, compat, count, affordance) for (affordance, (count, total, dist, transition, compat)) in affordance_times.items()]
            for (total, dist, transition, compat, count, affordance) in sorted(affordances, reverse=True):
                percent_multipler = 100/total
                file.write('{},{},{:0.04f},{:0.04f},{:0.04f},{:0.04f},{:0.04f},{:0.04f},{:0.04f},{:0.04f},{:0.02f},{:0.02f},{:0.02f}\n'.format(affordance, count, total, total/count, dist, dist/count, transition, transition/count, compat, compat/count, dist*percent_multipler, transition*percent_multipler, compat*percent_multipler))

        create_csv('autonomy_distance_estimate_times', callback=callback, connection=connection)
Esempio n. 12
0
def autonomy_distance_estimates_log_file(_connection=None):
    affordance_times = autonomy.autonomy_modes.g_affordance_times
    if affordance_times is None:
        return

    def callback(file):
        for (delta, count, _, affordance) in reversed(
                sorted([(delta, count, id(affordance), affordance)
                        for (affordance,
                             (count, delta)) in affordance_times.items()])):
            file.write('{},{},{}\n'.format(affordance, count, delta))

    create_csv('autonomy_distance_estimate_times',
               callback=callback,
               connection=_connection)
Esempio n. 13
0
def gather_tick_metrics_stop(_connection=None):
    def callback(file):
        zone = services.current_zone()
        tick_data = zone.tick_data
        zone.stop_gathering_tick_metrics()
        file.write(
            'ABSOLUTE TICKS,SIM NOW READABLE, SIM NOW TICKS,CLOCK SPEED ENUM,CLOCK SPEED MULTIPLIER,GAME TIME READABLE,GAME TIME TICKS,MULTIPLIER TYPE\n'
        )
        for data in tick_data:
            file.write('{},{},{},{},{},{},{},{}\n'.format(
                data.absolute_ticks, data.sim_now,
                data.sim_now.absolute_ticks(), data.clock_speed,
                data.clock_speed_multiplier, data.game_time,
                data.game_time.absolute_ticks(), data.multiplier_type))

    create_csv('tick_metrics', callback=callback, connection=_connection)
 def create_sim_resolver_view():
     for (tname, tmetrics) in event_testing.resolver.test_profile.items():
         datum_prefix = 'SingleSimResolver:'
         sim_resolver = tmetrics.resolvers.get('SingleSimResolver')
         if sim_resolver is None:
             datum_prefix = 'DoubleSimResolver:'
             sim_resolver = tmetrics.resolvers.get('DoubleSimResolver')
         if sim_resolver is None:
             continue
         for (resolver_datum, metrics) in sim_resolver.items():
             sim_resolvers[datum_prefix + resolver_datum].append(
                 (tname, metrics))
     filename = 'test_profile_sim_resolvers'
     create_csv(filename,
                callback=sim_resolver_callback,
                connection=_connection)
def dump_autonomy_profiling_data(_connection=None):
    output = sims4.commands.CheatOutput(_connection)
    if autonomy.autonomy_util.g_autonomy_profile_data is None:
        output(
            'Autonomy profiling is currently disabled. Use |performance.autonomy_profile.enable'
        )
        return
    if not autonomy.autonomy_util.g_autonomy_profile_data.autonomy_requests:
        output('Autonomy profiling is currently enabled but has no records.')
        return

    def callback(file):
        autonomy.autonomy_util.g_autonomy_profile_data.write_profiling_data_to_file(
            file)

    filename = 'autonomy_profile'
    create_csv(filename, callback=callback, connection=_connection)
Esempio n. 16
0
def dump_tests_profile(sort: SortStyle = SortStyle.AVERAGE_TIME,
                       _connection=None):
    output = sims4.commands.CheatOutput(_connection)
    if event_testing.resolver.test_profile is None:
        output(
            'Test profiling is currently disabled. Use |performance.test_profile.enable'
        )
        return
    if len(event_testing.resolver.test_profile) == 0:
        output('Test profiling is currently enabled but has no records.')
        return

    def sort_style(metric):
        if sort == SortStyle.AVERAGE_TIME:
            return metric.average_time
        if sort == SortStyle.TOTAL_TIME:
            return metric.total_time
        return metric.count

    def callback(file):
        TIME_MULTIPLIER = 1000
        file.write(
            'Test,Count,AverageTime(ms),TotalTime(ms),Resolver,Key,Count,AverageTime(ms),TotalTime(ms)\n'
        )
        for (test_name, test_metrics) in sorted(
                event_testing.resolver.test_profile.items(),
                key=lambda t: sort_style(t[1].metrics),
                reverse=True):
            file.write('{},{},{},{},,,,,\n'.format(
                test_name, test_metrics.metrics.count,
                test_metrics.metrics.average_time * TIME_MULTIPLIER,
                test_metrics.metrics.total_time * TIME_MULTIPLIER))
            for resolver in sorted(test_metrics.resolvers.keys()):
                data = test_metrics.resolvers[resolver]
                for (key, metrics) in sorted(data.items(),
                                             key=lambda t: sort_style(t[1]),
                                             reverse=True):
                    while metrics.average_time > 0:
                        file.write(',,,,{},{},{},{},{}\n'.format(
                            resolver, key, metrics.count,
                            metrics.average_time * TIME_MULTIPLIER,
                            metrics.total_time * TIME_MULTIPLIER))

    create_csv('test_profile', callback=callback, connection=_connection)
Esempio n. 17
0
def zone_gc_count_log_dump(_connection=None):
    output = sims4.commands.CheatOutput(_connection)
    if zone.gc_count_log is None:
        output(
            'Zone gc count logging is disabled. Enable with |mem.gc.zone_gc_count_log_start'
        )
        return

    def callback(file):
        file.write('zone_id, count, time\n')
        for (zone_id, count, time) in zone.gc_count_log:
            file.write('{:016x},{},{}\n'.format(zone_id, count, time))
        current_zone = services.current_zone()
        now = services.time_service().sim_now
        time_in_zone = now - current_zone._time_of_zone_spin_up
        minutes_in_zone = math.floor(time_in_zone.in_minutes())
        file.write('{:016x},{},{}\n'.format(current_zone.id,
                                            current_zone._gc_full_count,
                                            minutes_in_zone))

    create_csv('zone_gc_counts', callback=callback, connection=_connection)
def dump_test_resolver_profiles(_connection=None):
    TIME_MULTIPLIER = 1000

    def average_time(time, count):
        if time == 0 or count == 0:
            return 0
        return time * TIME_MULTIPLIER / count

    resolver_types = set()
    for (test_name,
         test_metrics) in event_testing.resolver.test_profile.items():
        resolver_types |= test_metrics.resolvers.keys()
    resolver_types = list(resolver_types)
    resolver_types.sort()

    def callback(file):
        file.write('Test,Count,AvgTime,ResolveTime,TestTime,{}\n'.format(
            ','.join('{}Count,{}'.format(x, x) for x in resolver_types)))
        for (test_name,
             test_metrics) in event_testing.resolver.test_profile.items():
            metrics = test_metrics.metrics
            file.write('{},{},{},{},{}'.format(
                test_name, metrics.count,
                average_time(metrics.get_total_time(), metrics.count),
                average_time(metrics.resolve_time, metrics.count),
                average_time(metrics.test_time, metrics.count)))
            for resolver_type in resolver_types:
                sub_metrics = test_metrics.resolvers.get(resolver_type)
                if sub_metrics is None:
                    file.write(',,')
                else:
                    count = sum(m.count for m in sub_metrics.values())
                    resolve_time = sum(m.resolve_time
                                       for m in sub_metrics.values())
                    file.write(',{},{}'.format(
                        count, average_time(resolve_time, count)))
            file.write('\n')

    filename = 'test_resolver_profile'
    create_csv(filename, callback=callback, connection=_connection)
 def create_test_view(sort_style):
     if sort_style != SortStyle.ALL:
         filename = 'test_profile_' + str(sort_style).replace('.', '_')
         create_csv(filename,
                    callback=test_callback,
                    connection=_connection)
def dump_relationship_object_information_per_sim(_connection=None):
    def callback(file):
        entries = []
        active_rel_objs = 0
        playable_rel_objs = 0
        unplayed_rel_obj = 0
        one_way_rel_obj = 0
        for x in services.sim_info_manager().values():
            total_rels = 0
            household_rels = 0
            rels_can_be_culled = 0
            rels_decaying = 0
            rels_target_unplayable = 0
            family_rels = 0
            rels_with_no_long_term_tracks = 0
            rels_target_playable = 0
            rels_target_active = 0
            for relationship in x.relationship_tracker:
                total_rels += 1
                decay_information = x.relationship_tracker.relationship_decay_metrics(
                    relationship.get_other_sim_id(x.sim_id))
                if decay_information is not None:
                    (decay_enabled, _, possible_tracks_decaying,
                     _) = decay_information
                    if decay_enabled:
                        rels_decaying += 1
                    elif possible_tracks_decaying == 0:
                        rels_with_no_long_term_tracks += 1
                target_sim_info = relationship.get_other_sim_info(x.sim_id)
                if target_sim_info is not None:
                    if target_sim_info.household_id == x.household_id:
                        household_rels += 1
                    elif any(bit.relationship_culling_prevention ==
                             RelationshipBitCullingPrevention.
                             PLAYED_AND_UNPLAYED
                             for bit in relationship._bits.values()):
                        family_rels += 1
                    else:
                        rels_can_be_culled += 1
                    if not target_sim_info.is_npc:
                        rels_target_active += 1
                    elif target_sim_info.is_played_sim:
                        rels_target_playable += 1
                    else:
                        rels_target_unplayable += 1
                    if not (x.is_npc and target_sim_info.is_npc):
                        active_rel_objs += 1
                    elif x.is_played_sim or target_sim_info.is_played_sim:
                        playable_rel_objs += 1
                    else:
                        unplayed_rel_obj += 1
                else:
                    one_way_rel_obj += 1
            entries.append('a{},{},{},{},{},{},{},{},{},{},{},{},{}\n'.format(
                x.id, x.first_name, x.last_name, total_rels,
                rels_can_be_culled, household_rels, family_rels,
                rels_target_active, rels_target_playable,
                rels_target_unplayable, rels_decaying,
                rels_with_no_long_term_tracks))
        total_rel_objects = active_rel_objs + playable_rel_objs + unplayed_rel_obj + one_way_rel_obj
        file.write('Metrics\n')
        file.write('#relationship python objs:,{}\n'.format(total_rel_objects))
        file.write(
            '#relationships one way objects:,{}\n'.format(one_way_rel_obj))
        file.write(
            '#relationships active objects:,{}\n'.format(active_rel_objs))
        file.write(
            '#relationships played objects:,{}\n'.format(playable_rel_objs))
        file.write(
            '#relationships unplayed objects:,{}\n\n'.format(unplayed_rel_obj))
        file.write(
            'SimID,FirstName,LastName,Played,RelationshipObjects,#Cullable,HouseholdConnected,BitPreventingCulling,WithActive,WithPlayable,WithUnplayayble,#Decaying,#NoLongTermTracks\n'
        )
        for row_entry in entries:
            file.write(row_entry)

    create_csv('relationship_objects_per_sim',
               callback=callback,
               connection=_connection)