Skip to content

Commit bd52051

Browse files
committed
Improve the efficiency of diff.
1 parent ec00dfe commit bd52051

File tree

1 file changed

+27
-7
lines changed

1 file changed

+27
-7
lines changed

src/stdlib_math_diff.fypp

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ contains
1818
${t1}$, intent(in), optional :: prepend(:), append(:)
1919
${t1}$, allocatable :: y(:)
2020
integer :: size_prepend, size_append, size_x
21-
${t1}$, allocatable :: work(:)
2221
integer :: n_, i
2322

2423
n_ = optval(n, 1)
@@ -38,16 +37,24 @@ contains
3837
return
3938
end if
4039

41-
allocate(work(size_x + size_prepend + size_append))
40+
#! Use a quick exit for the common case, to avoid memory allocation.
41+
if (size_prepend == 0 .and. size_append == 0 .and. n_ == 1) then
42+
y = x(2:) - x(1:size_x-1)
43+
return
44+
end if
45+
46+
block
47+
${t1}$ :: work(size_x + size_prepend + size_append)
4248
if (size_prepend > 0) work(:size_prepend) = prepend
4349
work(size_prepend+1:size_prepend+size_x) = x
4450
if (size_append > 0) work(size_prepend+size_x+1:) = append
4551

4652
do i = 1, n_
4753
work(1:size(work)-i) = work(2:size(work)-i+1) - work(1:size(work)-i)
4854
end do
49-
55+
5056
y = work(1:size(work)-n_)
57+
end block
5158

5259
end function diff_1_${k1}$
5360

@@ -58,7 +65,6 @@ contains
5865
${t1}$, allocatable :: y(:, :)
5966
integer :: size_prepend, size_append, size_x
6067
integer :: n_, dim_, i
61-
${t1}$, allocatable :: work(:, :)
6268

6369
n_ = optval(n, 1)
6470
if (n_ <= 0) then
@@ -87,19 +93,32 @@ contains
8793
return
8894
end if
8995

96+
#! Use a quick exit for the common case, to avoid memory allocation.
97+
if (size_prepend == 0 .and. size_append == 0 .and. n_ == 1) then
98+
if (dim_ == 1) then
99+
y = x(2:, :) - x(1:size_x-1, :)
100+
elseif (dim_ == 2) then
101+
y = x(:, 2:) - x(:, 1:size_x-1)
102+
end if
103+
return
104+
end if
105+
90106
if (dim_ == 1) then
91-
allocate(work(size_x+size_prepend+size_append, size(x, 2)))
107+
block
108+
${t1}$ :: work(size_x+size_prepend+size_append, size(x, 2))
92109
if (size_prepend > 0) work(1:size_prepend, :) = prepend
93110
work(size_prepend+1:size_x+size_prepend, :) = x
94111
if (size_append > 0) work(size_x+size_prepend+1:, :) = append
95112
do i = 1, n_
96113
work(1:size(work,1)-i, :) = work(2:size(work)-i+1, :) - work(1:size(x, 1)-i, :)
97114
end do
98115

99-
y = work(1:size(work)-n_, :)
116+
y = work(1:size(work,1)-n_, :)
117+
end block
100118

101119
elseif (dim_ == 2) then
102-
allocate(work(size(x, 1), size_x+size_prepend+size_append))
120+
block
121+
${t1}$ :: work(size(x, 1), size_x+size_prepend+size_append)
103122
if (size_prepend > 0) work(:, 1:size_prepend) = prepend
104123
work(:, size_prepend+1:size_x+size_prepend) = x
105124
if (size_append > 0) work(:, size_x+size_prepend+1:) = append
@@ -108,6 +127,7 @@ contains
108127
end do
109128

110129
y = work(:, 1:size(work,2)-n_)
130+
end block
111131

112132
end if
113133

0 commit comments

Comments
 (0)