С массивами можно работать и по указателям, причём Вы же мне и помогли разобраться, как это сделать. Обойти в прямом смысле слова нельзя, но можно оптимизировать алгоритм под конкретную задачу, а это можно сделать лишь имея все исходники(кроме самых базовых методов). Простой пример: есть динамическая библиотека Math.dll. В ней в классе Stepen объявлен метод НатСтепень(Число: Int32; Степень: Int32), возвращающий Int64. Я думаю, что единственный способ это реализовать следующий:
Library Math;
{$Reference 'System.dll'}
Uses System;
Type Stepen=Static Class
Public Static Function НатСтепень(Число: Int32; Степень: Int32): Int64;
Begin
Result:=Число;
For Var i:=0 to Степень-1 do
Result*=Число;
End;
End;
End.
В своей программе Вы подключаете библиотеку и используете вышеописанный метод, ведь это так удобно, метод универсальный, любую степень подписал и всё. Допустим, Вам нужно возвести в 4 степень массив из 100 чисел.
Если использовать библиотеку, то получим это:
{$Reference 'Math.dll'}
{$Reference 'System.dll'}
Uses Math;
Uses System;
Procedure ArrMul(arr: array of Single);
Begin
For Var i:=0 to arr.Length-1 do
arr[i]:=Stepen.НатСтепень(arr[i], 4);
End;
Begin
Var a:=new Single[100];
ArrMul(a);
End.
В принципе, всё хорошо… Или нет? Смотрим: у нас степень, всегда одна и та-же (4), причём совсем небольшая. Зачем использовать цикл для вычисления этой степени(библиотека Math)? Мы ведь с лёгкостью можем написать в программе это:
For Var i:=0 to arr.Length-1 do
Begin
Var Temp: Single:=arr[i];
arr[i]*=Temp;
arr[i]*=Temp;
arr[i]*=Temp;
End;
Что мы сделали? Очень много. Во-первых, мы “размотали” цикл, убрав таким образом как минимум инкрементацию счётчика и проверку на его соответствие параметру. В конкретно этом примере, это особой погоды не сделает, однако если у нас это место будет повторяться, скажем, 1000000 раз(а такое частенько бывает в нейросетях), то разница будет более чем существенная. Второе: мы отказались от использования метода НатСтепень, и, таким образом, избавились от безусловного перехода(вызова метода), который, являясь одной из команд процессора, требует времени и ресурсов. В итоге, от библиотеки, которая вполне может быть написана на C++ не осталось и следа, а наша программа имеет все шансы превзойти по скорости и потребляемой памяти версию с библиотекой. Это лишь малая часть. Рекомендую почитать следующую статью с Хабра: https://habr.com/post/165729/. Там подробно описаны приёмы оптимизации .NET приложений, кроме того есть результаты тестов, показывающие, что эти ребята переплюнули всех конкурентов, использующих C++. Одним словом - библиотеки предназначены для различных вариантов, то есть их методы или классы сделаны так, чтобы обеспечить максимальную гибкость и простоту при разработке, например, тот-же метод возведения в степень. Он, находясь в библиотеке, достаточно гибок, позволяет возводить в различные степени. Но за гибкость метода (как, в общем-то, и за красивую реализацию), как правило, приходится платить его эффективностью. Ваш пример с массивом правильный. Я пробовал(а теперь и использую) работать с элементами по указателям. Могу сказать только одно: ракообразность указателей с лихвой компенсируется скоростью. Особенно это касается Bitmap’ов(ускорение во много раз).