Судя по описанию, вся матрица помещается в один блок в памяти (как одномерный массив).
Поэтому бесплатный такой Resize: Cols1xRows1 = Cols2xRows2 = ... Чаще всего это преобразование матрица<->вектор.
Я уже думаю о возврате к массивам структур из за существенной разницы в скорости.
Заполнить через массив структур, а затем скопировать (кратковременное двойное потребление памяти) данные в matrix, работая уже с ней.
Полезное исследование, спасибо.
Поэтому бесплатный такой Resize: Cols1xRows1 = Cols2xRows2 = ... Чаще всего это преобразование матрица<->вектор.
Заполнить через массив структур, а затем скопировать (кратковременное двойное потребление памяти) данные в matrix, работая уже с ней.
Полезное исследование, спасибо.
А как то можно вместо обращения d[r].d[c] сделать d[r][c] для массивов структур (и чтение и запись)? Макросы или еще что-то? В таких вещах я не разбираюсь.
А как то можно вместо обращения d[r].d[c] сделать d[r][c] для массивов структур (и чтение и запись)? Макросы или еще что-то? В таких вещах я не разбираюсь.
Если перейти на классы, то несложно чтение сделать. Запись - тоже возможно. Одновременно - нет.
Однако, можно d[a[r][c]] и d[b[r][c]] для чтения и записи. Но стоит ли...
Теперь ясно, почему в старом алглибе чтение было через [][], а запись через Set().
Сейчас Алглиб уже на матрицы переделали.
Интересная ветка, да только все началось и кончилось на ресайзах. А эти операции довольно редкие. Я обычно заказываю статический массив с запасом. Один форумчанин (ник не помню (: ) писал, что, по его тестам, они работают быстрее динамических. Было бы интересно протестировать векторы, матрицы и массивы на арифметических операциях.
Я сейчас разрабатываю прототип EA на Matlab. А там как раз все операции все операции матричные. Даже умножение двух переменных типа double рассматривается, как произведение матриц :).
Задача первого этапа сделать на Matlab нативную DLL с возможностью использовать из ЕА МТ5. Пока компилирую ее в стиле С, возможно перейду на стили С++ и/или C#. Ну, а в финале придется переписывать все матлабовское на MQL5. Так что тема реального быстродействия очень интересна.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
И обоим измерениям можно в процессе работы изменять размер:
Обращение к ним только непривычное, не d[r][c], a d[r].d[c].
C появлением матриц обращение к элементам стало привычным, как в других ЯП d[r][c].
Судя по описанию, вся матрица помещается в один блок в памяти (как одномерный массив).
Часто заранее не знаешь, сколько строк и столбцов будет в матрице, поэтому нужно делать Resize по мере необходимости. Обычно число столбцов становится известным после заполнения первой строки, дальше оно не меняется. А вот число строк неизвестно. При оптимизации в зависимости от выбранных параметров оно может отличаться в сотни/тысячи раз.
Сравним скорость выполнения resize. Советник:
Переключая matrix_arr будем переключаться с матриц на массивы структур.
Самый оптимальный вариант сравнения скорости - оптимизация одним потоком (откл. все агенты, кроме первого) по параметру repeats, который ни на что не влияет в коде.
Сравним скорость Resize для 1000 столбцов и 2000, 10000 и 100000 строк:
Для 2000 на 1000 массивы изменяют размер за 0,9 сек, матрицы за 9,7 сек. Разница в 10 раз
Для 10000 на 1000 массивы изменяют размер за 2 сек, матрицы за 4 мин 8 сек. Разница в 124 раза.
Добавим резервирование памяти через 3-й параметр. Резервировать будем по 100 строк. Массивам добавляем резерв добавляем только когда меняем размер основного массива. Матрице резерв умножим на число столбцов, чтобы тесты были эквивалентными.
Сравниваем скорость:
Резерв помог, оба варианта стали быстрее.
Для 10 000 на 1000 массивы изменяют размер за 0,9 сек, матрицы за 3,2 сек. Разница в 3 раза
Для 100 000 на 1000 массивы изменяют размер за 2,2 сек, матрицы за 4 мин. Разница в 110 раз.
Полагаю столь существенная разница из за того, что массив структур не хранит сами структуры, а адреса на них (или адреса на массив в их составе). Т.е при добавлении новой строки создается массив размером в число столбцов в любой свободной области памяти, где есть для нее место.
При увеличении числа строк в мартице, которая идет одним блоком памяти, в ранее выбранной области памяти может не хватить свободного места в этот момент и появляется замедление - нужно занять новую область памяти, где есть требуемый размер и в нее копируется матрица из старого места. И это может происходить много раз, когда памяти в выбранном месте будет не хватать.
В общем то причина тормозов понятна.
На С++ аналогичную матрицу (с привычным доступом d[r][c] ) можно получить:
Если не ошибаюсь, первый массив содержит адреса в памяти, указываюшие на массивы второго уровня, которые уже содержат данные (построчно).
Жаль что MQ не пошли таким же путем, возможно работа с массивом массивов была бы быстрее, чем с единым блоком данных.
Я уже думаю о возврате к массивам структур из за существенной разницы в скорости. Непривычность всего лишь в доступе d[r].d[c].
Так же пока не сделано сохранение матриц в файл. Полагаю скопировать 1Гг памяти одним блоком в разы быстрее, чем 100 млн раз копировать поэлементно. Это второй тормоз в работе с матрицами.
Думаю старый вариант с дин. массивом структур в которой дин. массив будет быстрее, т.к. массив в структуре можно целиком в файл скинуть rows число раз.