Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.71/35: Рейтинг темы: голосов - 35, средняя оценка - 4.71
17 / 5 / 0
Регистрация: 16.04.2016
Сообщений: 371

Оптимизация кода по получению информации об играх из файла

08.04.2023, 00:44. Показов 8157. Ответов 46
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всех приветствую. Мне нужно получить из lua файлов имена и другую информацию об играх. В принципе мой код работает,но если в папке 70-80 и более игр,ui зависает где-то на пару секунд. Я не представляю,что будет,если в папке будет 300 игр. Я понимаю,что возможно мне надо делать это в отдельном потоке,но я не умею работать с потоками в mfc,да и,на мой взгляд,это не нужно,главное оптимизировать код и тогда,на мой взгляд,тормоза уменьшатся. Суть в том,что в каждой папке с игрой мы парсим первые 15 строк из некоторых lua файлов (main.lua и main3.lua) для получения нужной информации (подпапки в играх нас не интересуют). Затем мы добавляем недостающие игры,т.е те игры,которые мы установили вручную,в CListBox,но этот код я не буду выкладывать,т.к,на мой взгляд,он не вызывает тормоза. Вообще,как мне кажется,наибольшие тормоза из этого вызывают регулярки. Если в них основная проблема,подскажите пожалуйста,как обойтись без них,или какую более быструю библиотеку использовать для регулярок. approveInfo - мап типа string,std:air<string,int> (тип я пишу примерно). Вот фрагмент кода класса,в котором показан парсинг строк из файлов. Заранее всех благодарю за помощь по оптимизации этого счастья.

C++
1
2
3
4
5
6
7
8
9
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
static CString getGamesDir() {
    TCHAR buff[MAX_PATH];
    ::GetModuleFileName(NULL, buff, sizeof(buff));
    CString baseDir = buff;
    baseDir = baseDir.Left(baseDir.ReverseFind(_T('\\')) + 1);
    return baseDir + L"\\games\\";
}static CString getGamesDir() {
    TCHAR buff[MAX_PATH];
    ::GetModuleFileName(NULL, buff, sizeof(buff));
    CString baseDir = buff;
    baseDir = baseDir.Left(baseDir.ReverseFind(_T('\\')) + 1);
    return baseDir + L"\\games\\";
}static CString getGamesDir() {
    TCHAR buff[MAX_PATH];
    ::GetModuleFileName(NULL, buff, sizeof(buff));
    CString baseDir = buff;
    baseDir = baseDir.Left(baseDir.ReverseFind(_T('\\')) + 1);
    return baseDir + L"\\games\\";
}
static void ListFilesGamInDirectory(LPCTSTR dirName, std::vector<std::pair<CString/*full path*/, CString/*name*/> >& filepaths)
{
    // Check input parameters
    ASSERT(dirName != NULL);
    // Clear filename list
    filepaths.clear();
    // Object to enumerate files
    CFileFind finder;
    // Build a string using wildcards *.*,
    // to enumerate content of a directory
    CString wildcard(dirName);
    wildcard += _T("*.*");
    // Init the file finding job
    BOOL working = finder.FindFile(wildcard);
    // For each file that is found:
    while (working)
    {
        // Update finder status with new file
        working = finder.FindNextFile();
        // Skip '.' and '..'
        if (finder.IsDots())
        {
            continue;
        }
        // Skip sub-directories
        if (finder.IsDirectory())
        {
            // Add file path to container
            filepaths.push_back(std::make_pair(finder.GetFilePath(), finder.GetFileName()));
            continue;
        }
    }
    // Cleanup file finder
    finder.Close();
}
static CString get_game_property(std::wstring property, std::wstring inp) //входной текст
{
    //Обработка отображения объектов сцены
    const std::wregex regex_name(L"\\$\\s*?" + property + L"\\s*?:\\s*?([^\\$]*?)\\$", std::regex_constants::icase);
    std::wsregex_iterator next(inp.begin(), inp.end(), regex_name);
    std::wsregex_iterator end;
    while (next != end) {
        std::wsmatch match = *next;
        if (match.size() == 2)
        {
            CString nameStr(match[1].str().data());
            nameStr = nameStr.Trim(); //триммируем
            return nameStr;
        }
        next++;
    }
    return CString();
}
void LauncherDialog::RescanInstalled()
{
    //int result =std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
    std::vector<std::pair<CString, CString> > filePathsAndNames;
    /*installedGameNameCache.clear();
    m_listInstalled.DeleteAllItems();*/
    ListFilesGamInDirectory(getGamesDir(), filePathsAndNames);
 
    for (int i = 0; i < filePathsAndNames.size(); i++)
    {
        //if (installedGameNameCache.count(filePathsAndNames[i].second) > 0) continue;
        CString string;
        FILE* fStream;
        bool have_file = false;
        if (PathFileExists(filePathsAndNames[i].first + L"\\main.lua"))
        {
            _tfopen_s(&fStream, filePathsAndNames[i].first + L"\\main.lua", L"rt,ccs=UTF-8");
            have_file = true;
        }
        else if (PathFileExists(filePathsAndNames[i].first + L"\\main3.lua"))
        {
            _tfopen_s(&fStream, filePathsAndNames[i].first + L"\\main3.lua", L"rt,ccs=UTF-8");
            have_file = true;
        }
        if (have_file && installedGameNameCache.count(filePathsAndNames[i].second) == 0)installedGameNameCache.insert(filePathsAndNames[i].second);
        if (have_file)
        {
            CStdioFile gameFile(fStream);
            CString game_date;
            CString game_name;
            CString game_name_en;
            CString game_author;
            CString game_author_en;
            CString game_description;
            CString game_language;
            CString game_version;
            const int MAX_STR_CNT = 15; //не больше этого количества строк от начала
            int curr_str = 0;
            while (gameFile.ReadString(string))
            {
                std::wstring buf = string.GetBuffer();
                //MessageBox(buf, L"Тест");
                if (game_date.IsEmpty()) game_date = get_game_property(L"date", buf);
                if (game_name.IsEmpty()) game_name = get_game_property(L"name\\(ru\\s*?\\)", buf);
                if (game_name_en.IsEmpty()) game_name_en = get_game_property(L"name", buf);
                if (game_author_en.IsEmpty()) game_author = get_game_property(L"author", buf);
                if (game_author.IsEmpty()) game_name = get_game_property(L"author\\(ru\\s*?\\)", buf);
                if (game_description.IsEmpty()) game_description = get_game_property(L"info", buf);
                if (game_language.IsEmpty()) game_language = get_game_property(L"lang", buf);
                if (game_version.IsEmpty()) game_version = get_game_property(L"version", buf);
                //Если игра уже установлена,обновляем только версию.
                if (approveInfo.count(filePathsAndNames[i].second+suffix) > 0 && !game_version.IsEmpty()) {
if(game_version !=m_listInstalled.GetItemText(approveInfo[filePathsAndNames[i].second + suffix].second, N_SUBITEM_LIST_VERSION))SetCell(m_listInstalled, game_version, approveInfo[filePathsAndNames[i].second + suffix].second, N_SUBITEM_LIST_VERSION);
string.ReleaseBuffer();
                    break;
                }
                else if (!game_date.IsEmpty() && !game_name.IsEmpty() && !game_description.IsEmpty() && !game_version.IsEmpty() && !game_author.IsEmpty() && !game_language.IsEmpty())
                {
                    AddNewGame(game_date, game_name, game_author, game_description, game_version, game_language, filePathsAndNames[i], m_listInstalled);
                    string.ReleaseBuffer();
                    break;
                }
                string.ReleaseBuffer();
                curr_str++;
                if (curr_str > MAX_STR_CNT) break;
            }
            //Игра не находится в списке скаченных и мы не нашли всей информации
            if (!approveInfo.count(filePathsAndNames[i].second) && (game_date.IsEmpty() || game_name.IsEmpty() || game_description.IsEmpty() || game_author.IsEmpty() || game_language.IsEmpty() || game_version.IsEmpty()))
            {
                AddNewGame(game_date, game_name.IsEmpty() ? game_name_en : game_name, game_author.IsEmpty() ? game_author_en : game_author, game_description, game_language, game_version, filePathsAndNames[i], m_listInstalled);
            }
            gameFile.Close();
        }
    }
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
08.04.2023, 00:44
Ответы с готовыми решениями:

Оптимизация запроса по получению периода если дана дата
Всем привет! Дана таблица с записями (355к строк), в которой есть дата (dat) - начало действия этой строки (например, дата начала...

Оптимизация кода скрипта при большом объеме информации
Уважаемые друзья, нужна ваша помощь в оптимизации запроса, т.к. сервер не дает завершить выполнение скрипта, отдавая ошибку 504. Смысл...

Оптимизация программного кода (считывание информации с Edita в массивы )
Мне для программы нужно считать химическое уравнение с эдита, при этом нужно что бы даные разделялись по элементам, соответствующим им...

46
17 / 5 / 0
Регистрация: 16.04.2016
Сообщений: 371
27.04.2023, 21:59  [ТС]
Студворк — интернет-сервис помощи студентам
Понятно. А если я сделаю его статическим,но не членом класса,это тоже улучшит производительность? Интересно,почему это улучшит производительность,ведь мы же изначально создаём вектор нулевой длинны,или на его создание уходит много времени. Вообще rescanInstalled используется по требованию пользователя,т.е он,к примеру,не вызывается в таймере. Кстати Вы не ответили на вопрос по поводу порчи стека,т.е что это такое,просто я об этом в первый раз слышу.
0
фрилансер
 Аватар для Алексей1153
6510 / 5772 / 1135
Регистрация: 11.10.2019
Сообщений: 15,424
28.04.2023, 11:22
Цитата Сообщение от КАВ Посмотреть сообщение
А если я сделаю его статическим
если это позволяет алгоритм программы - на здоровье. Нужно учитывать, что таким глобальным объектом будут пользоваться все вызыватели функции. В том числе и многопоточные, если они есть

Цитата Сообщение от КАВ Посмотреть сообщение
Интересно,почему это улучшит производительность
если не пересоздавать вектор, то его capacity сама по себе не уменьшается. Можно сбросить size в ноль при помощи clear. Но новые push_back будут выполнятся быстро, так как память уже выделена ранее

Цитата Сообщение от КАВ Посмотреть сообщение
Вообще rescanInstalled используется по требованию пользователя
тогда нет смысла избегать реаллокаций, можно оставить так, как есть

Цитата Сообщение от КАВ Посмотреть сообщение
по поводу порчи стека,т.е что это такое,просто я об этом в первый раз слышу.
стек
http://incpu.ru/Arhitektura-mi... -Stek.html
http://mf.grsu.by/UchProc/liva... oal_11.htm

Добавлено через 2 минуты
локальные переменные размещаются на стеке. Если выйти за край памяти локальной переменной, то мы получаем неопределённое поведение. Технически - если мы туда пишем, то портим соседние переменные, аргументы функции и так далее
0
17 / 5 / 0
Регистрация: 16.04.2016
Сообщений: 371
28.04.2023, 23:15  [ТС]
Огромное спасибо. Всё-таки внедрил std::unordered_map и std::unordered_set,правда прироста скорости я почти не заметил. Может мой ког можно ещё как-то оптимизировать? В общем тут появилась ещё одна маленькая проблемка. Дело в том,что в описании игры есть символы типа и т.д. Вопрос,как оптимально эскеййпнуть их? Кстати заменил sizeof на std::size во всём проекте,поэтому Огромное Вам спасибо за то,что Вы посмотрели мой код.
0
фрилансер
 Аватар для Алексей1153
6510 / 5772 / 1135
Регистрация: 11.10.2019
Сообщений: 15,424
29.04.2023, 16:40
Цитата Сообщение от КАВ Посмотреть сообщение
Кстати заменил sizeof на std::size во всём проекте
простая огульная замена - это опасно. Каждый случай нужно рассмотреть. Возможно, где-то действительно нужен был sizeof
0
17 / 5 / 0
Регистрация: 16.04.2016
Сообщений: 371
01.05.2023, 14:41  [ТС]
Почему-то не вставились символы. Я имел ввиду,как эскейпнуть последовательности типа &#13 и т.д.
0
фрилансер
 Аватар для Алексей1153
6510 / 5772 / 1135
Регистрация: 11.10.2019
Сообщений: 15,424
01.05.2023, 15:40
КАВ,
C++
1
"текст\r\nтекст"
0
17 / 5 / 0
Регистрация: 16.04.2016
Сообщений: 371
03.05.2023, 18:50  [ТС]
Я думал,может есть встроенная функция по замене этих последовательностей,а получается мне всё придётся заменять самому,т.к кроме &#13 есть и другие символы.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
03.05.2023, 18:50

Литература по получению MD5 файла в C++ с CryptoApi
Помогите пожалуйста, требуется написать программу, которая выводит на экран хеш файла через CryptiApi. На сайте MSDN есть статейка: Example...

Оптимизация кода пакетного файла для создания бэкапов
Добрый день. Столкнулся с задачей: требуется оптимизировать создание бэкапов. деление на ежедневные, еженедельные и ежемесячные. Для...

Оптимизация методом Ньютона (нахождение точки минимума). Оптимизация кода
MATLAB только начал осваивать. Попытался реализовать нахождение точки минимума методом Ньютона для функции 2*X12 - X1*X2 + 3*X22 -...

Оптимизация кода. Замер времени выполнения части кода.
Доброе утро. Есть желание посмотреть сколько времени занимает выполнение какого-то блока кода/отдельной функции или процедуры/программы...

Алгоритм передачи информации в играх
Собрал простенькую игру компонентах IdTCPClient и IdTCPServer на делфи в крестики нолики. Можно играть ей на двух компьютерах используя...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
47
Ответ Создать тему
Новые блоги и статьи
Транслитерация текста с кириллицы на латиницу (вариант №2)
Maks 13.11.2026
Обновленная версия ранее созданной обработки. Добавлено: - Проверка исходного текста на кириллицу, через обращение к стандартной функции "ТолькоКириллицаВСтроке" из общего модуля. . .
Часы с термометром и праздничным календарем
yariko 12.11.2026
Сегодня мы рассмотрим как можно сделать отличные многофункциональные часы. Итак, поставим конкретную задачу: разработать часы с календарем, двумя термодатчиками, выводом поздравительных сообщений. . .
Транслитерация текста с кириллицы на латиницу (вариант №1)
Maks 11.11.2026
Решил облегчить жизнь себе и коллегам админам при создании электронных почтовых ящиков для пользователей, в результате написал обработку "Транслитерация текста" с кириллицы на латиницу, а в ней. . .
Книги по геймдизайну, левел-дизайну, игровым механикам и проектированию игрового опыта
8Observer8 08.11.2026
Содержание блога | English Version 1. 2003 - 06 - Designing Virtual Worlds (1st Edition) Автор: Richard A. Bartle | Объем: 768 стр. Ссылки: Amazon . . .
Родители токсичные абьюзеры по отношению к своим детям ругают их оскорбляют не любят
zorxor 08.11.2026
Жить в атмосфере постоянных оскорблений, критики и холодности со стороны родителей — это тяжелое и болезненное испытание, которое оставляет глубокие эмоциональные раны. Токсичное и абьюзивное. . .
Как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Ответ от Джемени ИИ.
zorxor 08.11.2026
Джемени, как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Многие люди, возвращаясь домой, сразу переодеваются в максимально свободную одежду или вовсе предпочитают. . .
Паттерн очереди действий/команд (Action / Command Queue). Система очереди действий и кат-сцен с SDL3 Callbacks, cglm и OpenGL
8Observer8 07.11.2026
Содержание блога | English Version Руководство для начинающих по реализации паттерна очереди действий/ команд (Action / Command Queue) на C++ (C++20) с использованием официального SDL3 Callbacks. . .
Проверка полного ФИО в типовом справочнике
Maks 07.11.2026
Решение реализовано в конфигурации КА2, на примере справочника "КонтактныеЛицаПартнеров". Задача: Запрет инициалов. Не допускаеть использование сокращений вида "И. И. ", "И. И. ", "И И" и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru