Функции, возвращающие кортежи, против процедур с выходными параметрами
Если подпрограмма вычисляет несколько выходных значений, то ее можно оформить либо как процедуру с передаваемыми по ссылке выходными параметрами, либо как функцию, возвращающую кортеж.
Сравним оба способа по читаемости и производительности.
Задача. Пусть нам следует вычислить периметр и площадь треугольника со сторонами x и y.
Решение 1. Составим процедуру с двумя входными и двумя выходными параметрами. Измерим производительность:
procedure CalcPerimeterSquare(x,y: integer; var P,S: real); begin P := 2*(x+y); S := x*y; end; begin var n := 100000000; var sw := new Stopwatch; sw.ReStart; loop n do begin var P,S: real; CalcPerimeterSquare(2,3,P,S); end; sw.Stop; Print(sw.ElapsedMilliseconds); end.
Данный код выполняется очень быстро:
46 мс
Решение 2. Реализуем вычисления в виде функции, возвращающей кортеж из двух значений:
function PerimeterSquare(x,y: real) := (2*(x+y), x*y); begin var n := 100000000; var sw := new Stopwatch; sw.Start; loop n do begin var (P,S) := PerimeterSquare(2,3); end; sw.Stop; Print(sw.ElapsedMilliseconds + ' мс'); end.
Код гораздо короче, но будет ли он быстрее?
292 мс
Однако вычисления здесь - простые: для вычисления площади и периметра используется два умножения и одно сложение.
Если рассмотреть более сложные вычисления, то именно они примут на себя основной удар, и разница по времени станет ничтожно мала:
procedure CalcPerimeterSquare(x,y: integer; var P,S: real); begin P := Sin(Exp(x) + Ln(y)); S := Tan(Exp(y)-Cos(x)); end; begin var n := 100000000; var sw := new Stopwatch; sw.ReStart; loop n do begin var P,S: real; CalcPerimeterSquare(2,3,P,S); end; sw.Stop; Print(sw.ElapsedMilliseconds + ' мс'); end.
function PerimeterSquare(x,y: real) := (Sin(Exp(x) + Ln(y)), Tan(Exp(y)-Cos(x))); begin var n := 100000000; var sw := new Stopwatch; sw.Start; loop n do begin var (P,S) := PerimeterSquare(2,3); end; sw.Stop; Print(sw.ElapsedMilliseconds + ' мс'); end.
Время работы примерно одинаково.
Заключение. Функции, возвращающие кортежи, - заманчивая синтаксическая возможность, укорачивающая код. Если вычисления достаточно долгие, то функции, возвращающие кортежи, - предпочтительный выбор. Если же вычисления - простые, то процедуры с параметрами-переменными работают значительно эффективнее.