Comments 13
(в delphi) range checks обычно отключаются после отладки (если нужна производительность).
Пока вижу проблему только в том, что SetLength() в конструкторе выделяет несколько блоков памяти (это может быть медленно).
Если нужна производительность, то, мне кажется, лучше хранить всё одним куском в памяти независимо от размеров и отдельно хранить размеры, сделать класс для каких-то базовых вещей вроде Create или извлечения элемента (это не так часто нужно, можно и с range check), а сами операции выполнять с помощью какой-нибудь OpenBLAS.
К удивлению, обнаружил, что, несмотря на возможности современной среды разработки, коллеги-программисты зачастую используют процедурный подход в решении подобных задач.
Это потому, что старые версии delphi (для которых, вероятно, писали код ваши коллеги) не поддерживали конструкторов для record'ов, перегрузки операторов, аннотаций, вот этого всего. Создавать объект класса, а потом освобождать его (.Free() ), было бы очень неудобно при использовании.
Вот это вот
TMatrix3x3 = array[1..3, 1..3] of Extended;
может размещаться на стеке, т.е. размещение выполняется очень быстро (просто изменение указателя стека), в отличие от вашего SetLength(a, m, n) (который ищет в куче (m+1) свободных блоков требуемого размера).
Если углубляться, доступ у "старой" версии тоже может быть чуть быстрее.
Но в целом, неплохо.
И почему для записей был выбран именно вариант constructor, а не function или procedure? Ведь для записей здесь не будет разницы (всегда есть не переопределяемый конструктор без параметров и выделение памяти осуществляется всегда). Да — всегда обновляй страницу — заметил, что вопрос задан, но ответом не доволен.
Конструктор использовал для наглядности — мы же «класс» проектируем :)
В самом деле — вектор может сожержать цедые числа, числа с плавающией запятой, двойной точности, extended, или наконец комплексные числа. И что на каждый тип элемента хранения писать свой новый класс и все сопутствующие алгоритмы??
Второй момент, матрицы — это не контейнеры, а математические объекты. Совсем разные понятия, лежащие в разных предметных областях. Контейнеры предназначены для хранения, для них определен стандартный интерфейс, куда должны входить методы «Добавить элемент» и «Удалить элемент». А матрицы применяются для решения систем уравнений и при рассмотрении линейных преобразований. Матрица — это частный случай тензора, а не контейнера.
Разве нельзя соорудить базовый класс с а весь набор арифметических операций вынести в отдельные private классы. А этот базовый при создании в зависимости от типа этого самого подключит нужный класс-реализацию? Для Extended свою, для целых свою и т.д.
Классы матриц и векторов в Delphi