Yes, there is an impact on memory and execution time - returning a reference returns a single (relatively small) scalar and nothing else. Returning an array or hash as a list makes a shallow copy of the array/hash and returns that, which can take up substantial time to make the copy and memory to store the copy if the array/hash is large.
The functional difference between the two is simply a question of whether you work with the result as an array/hash or as an arrayref/hashref. Some people consider references much more cumbersome to work with; personally, I don't consider it a significant difference.
Another functional difference is that you can't return multiple arrays or hashes as lists (they get flattened into a single list), but you can return multiple references. When this comes up, it's a killer detail that forces you to use references, but my experience is that it only comes up very rarely, so I don't know how important I'd consider it to be overall.
Going to the title question, I believe that the most important factor regarding returning lists vs. references is that you should be consistent so that you don't have to waste your time remembering which functions return arrays/hashes and which return references. Given that references are better in some situations and, at least for me, references are never significantly worse, I choose to standardize on always returning arrays/hashes as references rather than as lists.
(You could also choose to standardize on using wantarray
in your subs so that they'll return lists in list context and references in scalar context, but I tend to consider that to be a largely pointless over-complication.)