3

Of course I can just do

let dir = globpath('path', '*', 0, 1)
for file in dir
   if (isdirectory(file))
       add(myDirList, file)
   endif
endfor

But this will have to go through all the files in the directory and when the list is large this can take quite a long time. Is there a more efficient way of doing this?

Edit: Response to @Luc Hermitte

Testing globpath() and for loop together: 66.73 seconds.

Testing globpath() and filter together: 64.11 seconds.

A couple things to note about my specific situation.

  • I'm trying to access a network drive.
  • My first tests where done on wifi. I've connected with a hard wire and times have been reduced by about 25%.
  • The directory I'm accessing has ~2500 files/directories on it.

I've now tested the individual times on a hard wire connection and got the following times:

  • globpath(): 40.19 seconds
  • for loop: 4.96 seconds
  • filter: 4.91 seconds
  • system('dir "path"'): 0.17 seconds... (I'm on Windows obviously)

Not sure why for and filter are so close when I got better results with filter before...

So yeah, the external is magnitudes faster. You think this deserves a bug report?

P.S. I used globpath() because I didn't want to cd to the directory, but now I know that's not necessary.

2
  • Are external commands (e.g. find) an option? Apr 4, 2017 at 16:00
  • I'd prefer a native solution, but I could work with external.
    – Tumbler41
    Apr 4, 2017 at 16:04

1 Answer 1

3

:for loops are a performance nightmare.

Always prefer map() and filter() when you can.

Here, it would be:

let dir = globpath('path', '*', 0, 1)
call filter(dir, 'isdirectory(v:val)')
6
  • Sorry I meant to respond to this earlier, but things got a little crazy. Thanks for this. I'll definitely keep this in mind in the future. However for my particular case, the for isn't the biggest problem. Using a for took 66.73 seconds and using a filter took 64.11 seconds. An improvement yes, but it also shows that the biggest problem is the glob. Any alternative to a glob, or is it just moving to external commands to get that time down?
    – Tumbler41
    Apr 7, 2017 at 14:08
  • Don't worry. I'm quite surprised though that globpath() takes that much time for files in a single directory, compared to filter(). How many files are there in your directory? Or may be you're using **/*? How much time the equivalent (untested) echo "${paths[@]}" |xargs -L1 -I {} find {} -type d takes? If the simple globpath('path', '*', 0, 1) is that slow comparatively, it deserves a bug report IMO. BTW, if you have only one path, you could use glob() instead of globpath() Apr 7, 2017 at 15:54
  • Also, you should measure the time spent by globpath() itself, and the one took in filter() -- in case the real culprit is isdirectory(). Apr 7, 2017 at 15:55
  • Yeah, I think isdirectory() can be expansive. How about globpath('dir', '*/', 0, 1)? Apr 7, 2017 at 18:39
  • @ChristianBrabandt I thought of trying globpath('dir', '*/', 0, 1) but it still returns all files as well.
    – Tumbler41
    Apr 11, 2017 at 20:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.