Скоро будет MaxBy
, как в morelinq, тогда эта задача будет довольно просто решаться.
Просто она будет решаться, если будет какой-нибудь .Max2, возвращающий запись вида (индекс,значение). А еще в morelinq есть такая вкусняшка, как Index. Частенько не хватает… Но главное сейчас - это дождаться срезов. Вчера попалась задача порезать массив на три части и в каждой из них реверсировать элементы. На срезах бы решилось крайне элегантно, а так пришлось… ну, сами знаете)).
Да, действительно, когда я поснимал все “птички” в опциях компилятора, получил exe-файлы и запустил их из-под FAR-оболочки, получилось время 703 для статического массива и по 500 для динамических, независимо от использования Swap():
H:\PABCWork.NET>gj0.exe
-1
[[0.999999999999997,-3,2],[-3,3,-1],[2,-1,0]]
703
H:\PABCWork.NET>gj1.exe
-1
[[0.999999999999997,-3,2],[-3,3,-1],[2,-1,0]]
500
H:\PABCWork.NET>gj2.exe
-1
[[0.999999999999997,-3,2],[-3,3,-1],[2,-1,0]]
500
Ниже - тексты программ со статическими и динамическими массивами; вариант без Swap (gj1) приводить не стал.
// PascalABC.NET 3.1, сборка 1171 от 15.02.2016
type
tMatrix=array[1..3,1..3] of real;
tRVector=array[1..3] of real;
tIVector=array[1..3] of integer;
procedure inversion2(n:integer; eps:real; var a:tMatrix; var det:real);
// Обращение матрицы методом Гаусса-Жордана
// Алгоритм 120б. В кн. "Библиотека алгоритмов 101б-150б",
// М.И.Агеев, В.П.Алик, Ю.И.Марков. М.,"Советское радио", 1978
label
rept,nexti;
var
y,w:real;
i,j,k,r,p:integer;
b,c:trVector;
z:tIVector;
begin
det:=1.0;
for j:=1 to n do z[j]:=j;
for i:=1 to n do begin
k:=i; y:=a[i,i];
r:=i-1; p:=i+1;
for j:=p to n do begin
w:=a[i,j];
if abs(w)>abs(y) then begin k:=j; y:=w end
end;
det:=y*det;
if abs(y)<eps then Exit;
y:=1/y;
for j:=1 to n do begin
c[j]:=a[j,k]; a[j,k]:=a[j,i];
a[j,i]:=-c[j]*y;
a[i,j]:=a[i,j]*y; b[j]:=a[i,j]
end;
a[i,i]:=y;
j:=z[i]; z[i]:=k; z[k]:=j;
for k:=1 to r do begin
for j:=1 to r do a[k,j]:=a[k,j]-b[j]*c[k];
for j:=p to n do a[k,j]:=a[k,j]-b[j]*c[k]
end;
for k:=p to n do begin
for j:=1 to r do a[k,j]:=a[k,j]-b[j]*c[k];
for j:=p to n do a[k,j]:=a[k,j]-b[j]*c[k]
end;
end;
for i:=1 to n do begin
rept:
k:=z[i];
if k=i then goto nexti;
for j:=1 to n do begin
w:=a[i,j]; a[i,j]:=a[k,j]; a[k,j]:=w
end;
p:=z[i]; z[i]:=z[k]; z[k]:=p;
det:=-det;
goto rept;
nexti:
end
end;
begin
var eps:=0.1e-6;
var n:=3;
var dt:real;
var a:tMatrix;
for var i:=1 to 1000000 do begin
a[1,1]:=1; a[1,2]:=2; a[1,3]:=3;
a[2,1]:=2; a[2,2]:=4; a[2,3]:=5;
a[3,1]:=3; a[3,2]:=5; a[3,3]:=6;
inversion2(n,eps,a,dt);
end;
Writeln(dt);
Writeln(a);
Writeln(Milliseconds)
end.
// PascalABC.NET 3.1, сборка 1171 от 15.02.2016
procedure inversion2(n:integer; eps:real; var a:array[,] of real; var det:real);
// Обращение матрицы методом Гаусса-Жордана
// Алгоритм 120б. В кн. "Библиотека алгоритмов 101б-150б",
// М.И.Агеев, В.П.Алик, Ю.И.Марков. М.,"Советское радио", 1978
label
rept,nexti;
var
y,w:real;
i,j,k,r,p:integer;
b,c:array of real;
z:array of integer;
begin
SetLength(b,n); SetLength(c,n); SetLength(z,n);
det:=1.0;
for j:=0 to n-1 do z[j]:=j;
for i:=0 to n-1 do begin
k:=i; y:=a[i,i];
r:=i-1; p:=i+1;
for j:=p to n-1 do begin
w:=a[i,j];
if abs(w)>abs(y) then begin k:=j; y:=w end
end;
det:=y*det;
if abs(y)<eps then Exit;
y:=1/y;
for j:=0 to n-1 do begin
c[j]:=a[j,k]; a[j,k]:=a[j,i];
a[j,i]:=-c[j]*y;
a[i,j]:=a[i,j]*y; b[j]:=a[i,j]
end;
a[i,i]:=y;
j:=z[i]; z[i]:=k; z[k]:=j;
for k:=0 to r do begin
for j:=0 to r do a[k,j]:=a[k,j]-b[j]*c[k];
for j:=p to n-1 do a[k,j]:=a[k,j]-b[j]*c[k]
end;
for k:=p to n-1 do begin
for j:=0 to r do a[k,j]:=a[k,j]-b[j]*c[k];
for j:=p to n-1 do a[k,j]:=a[k,j]-b[j]*c[k]
end;
end;
for i:=0 to n-1 do begin
rept:
k:=z[i];
if k=i then goto nexti;
for j:=0 to n-1 do Swap(a[i,j],a[k,j]);
Swap(z[i],z[k]);
det:=-det;
goto rept;
nexti:
end
end;
begin
var eps:=0.1e-6;
var n:=3;
var dt:real;
var a:array[,] of real;
SetLength(a,3,3);
for var i:=1 to 1000000 do begin
a[0,0]:=1; a[0,1]:=2; a[0,2]:=3;
a[1,0]:=2; a[1,1]:=4; a[1,2]:=5;
a[2,0]:=3; a[2,1]:=5; a[2,2]:=6;
inversion2(n,eps,a,dt);
end;
Writeln(dt);
Writeln(a);
Writeln(Milliseconds)
end.
Получается, что в данной реализации компилятора работа с динамическими массивами производительнее. Возможно, причина тут именно в моделировании статических массивов посредством динамических.
Я списывался с ними - они сказали, что у них 3.0 и в следующее обновление будет 3.1, а на сайте написана неправда.
Улыбнуло. Но отрадно, что движение есть. А то дети интересуются, какой смысл изучать новшества, если их применить негде. Каждому не объяснишь, что это новое - на самом деле инвестиции в будущее для тех, кто решил так или иначе заниматься программированием.
Вот в этой статье http://pascalabc.net/stati-po-pascalabc-net/obuchenie-programmirovaniyu/28-meryaem-proizvoditelnost при ее подготовке я в разных вариантах пробовал и статические и динамические массивы. И - то одни работали быстрее, то другие. Я сделал вывод, что сильнее всего тут попадание в кеш процессора.
Вполне вероятно, что Вы правы в своем предположении. Спасибо за ссылку, интересный материал.