Общую тему пока не могу подобрать по алгосу. Прост ради теста переписываю одну прожку с шарпа на плюсы в целях самообразования. Подскажите, можно ли ускорить данный код, а конкретно цикл for (int j = 0; j < keys.size(); j++) в функции eb. Код (C++): #include <iostream> #include <Windows.h> #include <iostream> #include <fstream> #include <sstream> #include <string> #include <cstdint> #include "logger.h" using namespace std; template<typename T> size_t vectorsizeof(const typename std::vector<T>& vec) { return sizeof(T) * vec.size(); } std::vector<BYTE> readFile(const char* filename) { // open the file: std::ifstream file(filename, std::ios::binary); // read the data: return std::vector<BYTE>((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>()); } // инвертер операндов std::string rop(const std::string &op) { if (op == "^") { return"^"; } else if (op == "-") { return "+"; } else if (op == "+") { return "-"; } return ""; } // TODO: Проверить на точность std::vector<BYTE> eb(std::vector<std::string> &op, std::vector<BYTE> &list, std::vector<std::string> &keys, int len) { std::vector<BYTE> a = list; for (int i = 0; i < len; i++) { LOG(INFO, "PROCESSING :: EB") << i << "\n"; for (int j = 0; j < keys.size(); j++) { if (op[j] == "^") { a[i] = list[i] ^ static_cast<char>((keys[j].substr(2), 16)); } else if (op[j] == "-") { a[i] = list[i] - static_cast<char>((keys[j].substr(2), 16)); } else if (op[j] == "+") { a[i] = list[i] + static_cast<char>((keys[j].substr(2), 16)); } } } return a; } int main() { AixLog::Log::init<AixLog::SinkCout>(AixLog::Severity::debug); LOG(INFO, "INIT") << "The program has started\n"; vector<BYTE> file = readFile("target"); LOG(INFO, "INIT") << "File read successfully, size: " << vectorsizeof(file) << " bytes\n"; // test param vector<BYTE> file_test = { 77,90,144,0,3 }; vector<string> op = { "-", "+", "^", "-", "-"}; // seed vector<string> keys = { "0xCE", "0x5F", "0x8F", "0x42", "0xD1" }; int len = 5; // file size auto eb_test = eb(op, file, keys, vectorsizeof(file)); std::cout << "Hello World!\n"; }
Ну сравнения строк можно заменить на сравнение символов. Substr аллоцирует на куче вроде, можно от нее избавиться.
galenkane, Не знаю как делается в языках высокого уровня табличное преобразование вместо "если ... иначе если". ASM MovZx eAx,B_[op] Mov Al,[RecodeTab + eAx] ; таблица на 256 байт есть специальная xlat, но мне проще так.
Ваш "op" является указателем (индексом) в таблице (массиве) из соотв. 256 байт или в сисичках нет массивов или их индексов?!
op в // инверторе операндов или op[j] в eb - нет разницы: береся его байтное значение в качестве индекса константного (статического) массива для преобразования.
Конечно, вот так: Код (C): static uint8_t* eb (const uint8_t* data, uint32_t size, const char* op, const uint8_t* keys, uint32_t length) { uint8_t* a; uint32_t i, j; a = (uint8_t*)memdup (data, size); for (i=0; i<size; i++) { for (j=0; j<length; j++) { if (op[j] == '-') a[i] -= keys[j]; else if (op[j] == '+') a[i] += keys[j]; else if (op[j] == '^') a[i] ^= keys[j]; } } return a; } ... const char* op = "-+^--"; const uint8_t keys[] = {0xCE, 0x5F, 0x8F, 0x42, 0xD1}; uint8_t* eb_test = eb (data, size, op, keys, sizeof(keys)); free (eb_test); Вангую минимум пятикратный прирост скорости
Ну-ну Код (C): int main() { string_t msg; timer_t timer; void* data; uint32_t size; string_init (&msg, NULL); timer = timer_create (); data = file_load ("c:\\test.dat", &size); rtl_free (data); string_appendf (&msg, "File size: %u\n", size); timer_start (timer); test_stl (); timer_stop (timer); string_appendf (&msg, "STL version: %.4f sec\n", (double)timer_duration (timer) / 1000000); timer_start (timer); test_some_good_stuff_lol (); timer_stop (timer); string_appendf (&msg, "Normal version: %.4f sec\n", (double)timer_duration (timer) / 1000000); Clipboard_SetTextA (NULL, msg.cstr); timer_destroy (timer); string_clear (&msg); return 0; } Код (Text): File size: 86055644 STL version: 18.4913 sec Normal version: 0.8972 sec
Вот прекрасное доказательство, зачем нужно учить Си. И что процедурный подход на чистом коде все еще уделывает все эти ваши ООП, СТЛ, ПНХ и прочие расты.
Спойлер Оксюморон: Адепты сишечки без единого коммита в kernel. Cравнивать с хреновой реализацией на плюсах и приводить это как доказательство того, что кресты плохой язык в целом - это какое-то новое пробитие дна от форумных экспертов.