Ускорение алгоритма

Тема в разделе "WASM.BEGINNERS", создана пользователем galenkane, 27 фев 2021.

  1. galenkane

    galenkane Active Member

    Публикаций:
    0
    Регистрация:
    13 янв 2017
    Сообщения:
    269
    Общую тему пока не могу подобрать по алгосу. Прост ради теста переписываю одну прожку с шарпа на плюсы в целях самообразования.

    Подскажите, можно ли ускорить данный код, а конкретно цикл for (int j = 0; j < keys.size(); j++) в функции eb.

    Код (C++):
    1.  
    2. #include <iostream>
    3. #include <Windows.h>
    4. #include <iostream>
    5. #include <fstream>
    6. #include <sstream>
    7. #include <string>
    8. #include <cstdint>
    9.  
    10. #include "logger.h"
    11. using namespace std;
    12.  
    13. template<typename T>
    14. size_t vectorsizeof(const typename std::vector<T>& vec)
    15. {
    16.     return sizeof(T) * vec.size();
    17. }
    18.  
    19. std::vector<BYTE> readFile(const char* filename)
    20. {
    21.     // open the file:
    22.     std::ifstream file(filename, std::ios::binary);
    23.  
    24.     // read the data:
    25.     return std::vector<BYTE>((std::istreambuf_iterator<char>(file)),
    26.         std::istreambuf_iterator<char>());
    27. }
    28.  
    29. // инвертер операндов
    30. std::string rop(const std::string &op)
    31. {
    32.     if (op == "^")
    33.     {
    34.         return"^";
    35.     }
    36.     else if (op == "-")
    37.     {
    38.         return "+";
    39.     }
    40.     else if (op == "+")
    41.     {
    42.         return "-";
    43.     }
    44.     return "";
    45. }
    46.  
    47. // TODO: Проверить на точность
    48. std::vector<BYTE> eb(std::vector<std::string> &op, std::vector<BYTE> &list, std::vector<std::string> &keys, int len)
    49. {
    50.     std::vector<BYTE> a = list;
    51.     for (int i = 0; i < len; i++)
    52.     {
    53.         LOG(INFO, "PROCESSING :: EB") << i << "\n";
    54.  
    55.         for (int j = 0; j < keys.size(); j++)
    56.         {
    57.             if (op[j] == "^")
    58.             {
    59.                 a[i] = list[i] ^ static_cast<char>((keys[j].substr(2), 16));
    60.             }
    61.             else if (op[j] == "-")
    62.             {
    63.                 a[i] = list[i] - static_cast<char>((keys[j].substr(2), 16));
    64.             }
    65.             else if (op[j] == "+")
    66.             {
    67.                 a[i] = list[i] + static_cast<char>((keys[j].substr(2), 16));
    68.             }
    69.         }
    70.     }
    71.     return a;
    72. }
    73.  
    74. int main()
    75. {
    76.     AixLog::Log::init<AixLog::SinkCout>(AixLog::Severity::debug);
    77.     LOG(INFO, "INIT") << "The program has started\n";
    78.  
    79.     vector<BYTE> file = readFile("target");
    80.     LOG(INFO, "INIT") << "File read successfully, size: " << vectorsizeof(file) << " bytes\n";
    81.  
    82.     // test param
    83.     vector<BYTE> file_test = { 77,90,144,0,3 };
    84.     vector<string> op = { "-", "+", "^", "-", "-"}; // seed
    85.     vector<string> keys = { "0xCE", "0x5F", "0x8F", "0x42", "0xD1" };
    86.     int len = 5; // file size
    87.  
    88.     auto eb_test = eb(op, file, keys, vectorsizeof(file));
    89.  
    90.     std::cout << "Hello World!\n";
    91. }
    92.  
     
  2. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.250
    Ну сравнения строк можно заменить на сравнение символов. Substr аллоцирует на куче вроде, можно от нее избавиться.
     
  3. R81...

    R81... Active Member

    Публикаций:
    0
    Регистрация:
    1 фев 2020
    Сообщения:
    141
    galenkane, Не знаю как делается в языках высокого уровня табличное преобразование вместо "если ... иначе если".
    ASM
    MovZx eAx,B_[op]
    Mov Al,[RecodeTab + eAx] ; таблица на 256 байт
    есть специальная xlat, но мне проще так.
     
    algent нравится это.
  4. galenkane

    galenkane Active Member

    Публикаций:
    0
    Регистрация:
    13 янв 2017
    Сообщения:
    269
    та это задача просто для плюсиков без асма
     
  5. R81...

    R81... Active Member

    Публикаций:
    0
    Регистрация:
    1 фев 2020
    Сообщения:
    141
    Ваш "op" является указателем (индексом) в таблице (массиве) из соотв. 256 байт или в сисичках нет массивов или их индексов?!
     
    algent нравится это.
  6. galenkane

    galenkane Active Member

    Публикаций:
    0
    Регистрация:
    13 янв 2017
    Сообщения:
    269
    op массив из строк
     
  7. R81...

    R81... Active Member

    Публикаций:
    0
    Регистрация:
    1 фев 2020
    Сообщения:
    141
    op в // инверторе операндов или op[j] в eb - нет разницы: береся его байтное значение в качестве индекса константного (статического) массива для преобразования.
     
  8. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    Конечно, вот так:
    Код (C):
    1.  
    2. static uint8_t* eb (const uint8_t* data, uint32_t size, const char* op, const uint8_t* keys, uint32_t length)
    3. {
    4.     uint8_t* a;
    5.     uint32_t i, j;
    6.    
    7.     a = (uint8_t*)memdup (data, size);
    8.     for (i=0; i<size; i++)
    9.     {
    10.         for (j=0; j<length; j++)
    11.         {
    12.             if (op[j] == '-')
    13.                 a[i] -= keys[j];
    14.             else if (op[j] == '+')
    15.                 a[i] += keys[j];
    16.             else if (op[j] == '^')
    17.                 a[i] ^= keys[j];
    18.         }
    19.     }
    20.    
    21.     return a;
    22. }
    23. ...
    24. const char* op = "-+^--";
    25. const uint8_t keys[] = {0xCE, 0x5F, 0x8F, 0x42, 0xD1};
    26.  
    27. uint8_t* eb_test = eb (data, size, op, keys, sizeof(keys));
    28. free (eb_test);
    29.  
    Вангую минимум пятикратный прирост скорости :)
     
    M0rg0t нравится это.
  9. galenkane

    galenkane Active Member

    Публикаций:
    0
    Регистрация:
    13 янв 2017
    Сообщения:
    269
    2.6 против 2.5 секунды :lol:

    https://dropmefiles.com/2bRKJ log
     
  10. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    Ну-ну :)

    Код (C):
    1.  
    2. int main()
    3. {
    4.     string_t msg;
    5.     timer_t timer;
    6.     void* data;
    7.     uint32_t size;
    8.  
    9.     string_init (&msg, NULL);
    10.     timer = timer_create ();
    11.  
    12.     data = file_load ("c:\\test.dat", &size);
    13.     rtl_free (data);
    14.  
    15.     string_appendf (&msg, "File size: %u\n", size);
    16.  
    17.     timer_start (timer);
    18.     test_stl ();
    19.     timer_stop (timer);
    20.  
    21.     string_appendf (&msg, "STL version: %.4f sec\n", (double)timer_duration (timer) / 1000000);
    22.  
    23.     timer_start (timer);
    24.     test_some_good_stuff_lol ();
    25.     timer_stop (timer);
    26.  
    27.     string_appendf (&msg, "Normal version: %.4f sec\n", (double)timer_duration (timer) / 1000000);
    28.  
    29.     Clipboard_SetTextA (NULL, msg.cstr);
    30.  
    31.     timer_destroy (timer);
    32.     string_clear (&msg);
    33.     return 0;
    34. }
    35.  
    Код (Text):
    1.  
    2. File size: 86055644
    3. STL version: 18.4913 sec
    4. Normal version: 0.8972 sec
    5.  
     
    M0rg0t нравится это.
  11. galenkane

    galenkane Active Member

    Публикаций:
    0
    Регистрация:
    13 янв 2017
    Сообщения:
    269
    верю вам, нужны тесты еще
     
  12. galenkane

    galenkane Active Member

    Публикаций:
    0
    Регистрация:
    13 янв 2017
    Сообщения:
    269
    Нашел выход, компилируя данный кодес на линуксе) Там все намного быстрее)
     
  13. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.250
    Ха-ха, да, это известная история)).
     
  14. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.574
    Вот прекрасное доказательство, зачем нужно учить Си. И что процедурный подход на чистом коде все еще уделывает все эти ваши ООП, СТЛ, ПНХ и прочие расты.
     
    UbIvItS нравится это.
  15. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.250
    Медленный код можно писать на любом языке программирования, это от головы зависит.
     
  16. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    Да. А быстрый - не на любом :)
     
    UbIvItS, M0rg0t и youneuoy нравится это.
  17. galenkane

    galenkane Active Member

    Публикаций:
    0
    Регистрация:
    13 янв 2017
    Сообщения:
    269
    на самом деле все быстренько работает) процы тащат
     
  18. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.087
    линь на реальном железе иль под виртой?
     
  19. jega

    jega New Member

    Публикаций:
    0
    Регистрация:
    15 июн 2020
    Сообщения:
    13
    Оксюморон: Адепты сишечки без единого коммита в kernel.
    Cравнивать с хреновой реализацией на плюсах и приводить это как доказательство того, что кресты плохой язык в целом - это какое-то новое пробитие дна от форумных экспертов.
     
    Rel нравится это.
  20. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.250
    Добро пожаловать на васм, бро.