Hi, oidvectortypes() converts a vector of OIDs to a string of concatenated type names. Since it is typically used to display function argument types, the input vectors are usually short. However, if we pass a long vector, this function has a few issues:
* It uses strcat() to concatenate each type name. strcat() always needs to scan
from the beginning of the result string to its end, making this slow for long
vectors. We can simply keep a pointer to the end of the result string and
append directly there.
* There is no interrupt check in the loop, so cancellation can be delayed for
long vectors.
* format_type_extended() returns an allocated string, but that string is not
freed after being copied into the result. When the input is short, this is not
a problem, we can rely on the memory context to free the memory. But when the
vector is large, it is better to free these strings to avoid accumulating
unnecessary memory.
To compare the performance:
Before the patch:
```
evantest=# SELECT length(oidvectortypes(repeat('0 ', 400000)::oidvector));
length
---------
1199998
(1 row)
Time: 7364.353 ms (00:07.364)
```
After the patch:
```
evantest=# SELECT length(oidvectortypes(repeat('0 ', 400000)::oidvector));
length
---------
1199998
(1 row)
Time: 20.638 ms
```
Going from 7 seconds to 20 ms is a significant improvement for this large
input. Although the benefit in normal use is limited, this seems like a small,
worthwhile change.
Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/
v1-0001-Avoid-repeated-scans-of-the-output-buffer-in-oidv.patch
Description: Binary data
