@StillDontKnowMyName
Кодер одного маленького проекта, к тому же новичок

Как оптимизировать запись классов из памяти?

Задача была довольно простая: подгружаемая в процесс длл должна считать из памяти процесса записанные там данные о классах и упорядочить их.

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

class ClientClass
{
public:
	const char* m_pNetworkName;
	Table* m_pTable;
	ClientClass* m_pNext;
};


Table в свою очередь тоже класс и содержит он структуры, в которых хранится информация о членах класса - Prop:

struct Table
{
	Prop* m_pProps;              // Указатель на массив Prop'ов
	int m_iProps;                   // количество Prop в Table
	char* m_pNetTableName;
};

struct Prop
{
	char* m_pVarName;      // название члена класса
	Table* m_pDataTable;
	int m_Offset;                // смещение указателя Prop относительно указателя Table
};


Обратите внимание на то, что внутри Prop может оказаться Table, инфу из которой также нужно прочитать.

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

Моя реализация записи в текстовый файл (макрос LOG записывает с новой строки string в текстовый файл):

std::vector<std::string> base_classes;
static int class_level{ 0 };

void WriteAllOffsetsInLog()
	{
		// получаем указатель на первый класс
		auto cl_class = Cl->GetFirstClass();
		if (!cl_class)
			return;

		// сохраняем имена основных классов, чтобы не перечислять их члены в дочерних классах
		while (cl_class)
		{
			auto table = cl_class->m_pTable;

			if (table && table->m_iProps)
				base_classes.push_back(table->m_pNetTableName);

			cl_class = cl_class->m_pNext;
		}

		// снова находим первый класс
		cl_class = Cl->GetFirstClass();
		if (!cl_class)
			return;

		while (cl_class)
		{
			auto table = cl_class->m_pTable;

			if (table && table->m_iProps)
			{
				class_level = 1;
				// эта функция работает со структурами table и props
				WriteClass(table, cl_class->m_pNetworkName);
			}

			cl_class = cl_class->m_pNext;
		}
	}

	void WriteClass(Table* table, std::string name, int off = 0)
	{
		// добавляем табы в строчку в зависимости от того, насколько глубоко расположен класс в общем дереве
		std::string tabtab = std::string();
		for (int w = 0; w < class_level - 1; w++)
			tabtab += "    ";

		std::string define_class { tabtab };
		define_class += "class    ";
		define_class += name;

		for (int i = 0; i < table->m_iProps; i++)
		{
			auto prop = table->m_pProps[i];
			// перечисляем включённые классы справа от имени дочернего
			if (prop.m_Offset == NULL && prop.m_pDataTable && prop.m_pDataTable->m_iProps && IsBaseClass(prop.m_pDataTable))
			{
				define_class += "  :  public ";
				define_class += prop.m_pDataTable->m_pNetTableName;
			}
		}

		if (off)   // указатель класса смещён относительно материнского класса
		{
			define_class += "    //        ";
			define_class += to16(off);
		}

		LOG(define_class);
		LOG(tabtab + "{");
		LOG(tabtab + "public:");

		записываем члены класса
		for (int i = 0; i < table->m_iProps; i++)
		{
			auto intabtab = tabtab + "    ";

			auto prop = table->m_pProps[i];

			auto offset = to16(prop.m_Offset);

			auto new_table = prop.m_pDataTable;
			if (new_table) // член класса оказался классом и нужно вызвать функцию, которая запишет члены этого класса
			{
				if (!prop.m_Offset && IsBaseClass(new_table)) // оказалось, это не член класса, а включённый класс который будет расписан отдельно
					continue;

				if (new_table->m_iProps)
				{
					class_level++;
					WriteClass(new_table, new_table->m_pNetTableName, prop.m_Offset);
					class_level--;
				}
			}
			else if (prop.m_Offset) // это просто переменная, запишем её смещение указателя
			{
				std::string log = intabtab;

				log += "uintptr_t    ";
				log += prop.m_pVarName;
				log += " = ";
				log += offset;
				log += ";";
				LOG(log);
			}
		}

		LOG(tabtab + "};");
		LOG("");

		if (class_level == 1)
			LOG("");
	}


Подскажите, как этот код оптимизировать? Он не оптимизирован от слова совсем, профайлинг выявил, что больше всего времени занимают операции с std::vector.
  • Вопрос задан
  • 91 просмотр
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы