function executable() is too slow on windows

138 views
Skip to first unread message

Yasuhiro MATSUMOTO

unread,
Jan 30, 2009, 1:12:43 AM1/30/09
to vim...@vim.org, Bram Moolenaar
Hi, bram and all.

function executable() is too slow on windows. it seems that using
SearchPath() API.
SearchPath() tries following sequence if lp.

1. Location at executable.
2. Current directory
3. Windows System Direction which can get with GetSystemDirectory().
4. Windows Directory.
5. Specified as PATH environment variable.

* see remarks at
http://msdn.microsoft.com/en-us/library/aa365527%28VS.85%29.aspx

I guess that No3, No4, No5 is duplicated and I guess that No5 include
No3 and No4.
For size, I tried following patch and function executable() had few
speed-up. :-)
If i use netrw.vim then it took 3 seconds for getting password prompt
from type ':e ftp://xxx'.
But it took 1.5 seconds for them with following patch.

Thanks.

Index: src/os_win32.c
===================================================================
--- src/os_win32.c (revision 1326)
+++ src/os_win32.c (working copy)
@@ -1594,7 +1594,7 @@

if (p != NULL)
{
- n = (long)SearchPathW(NULL, p, NULL, _MAX_PATH, fnamew, &dumw);
+ n = (long)SearchPathW(_wgetenv(L"PATH"), p, NULL, _MAX_PATH,
fnamew, &dumw);
vim_free(p);
if (n > 0 || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
{
@@ -1608,7 +1608,7 @@
}
}
#endif
- if (SearchPath(NULL, name, NULL, _MAX_PATH, fname, &dum) == 0)
+ if (SearchPath(getenv("PATH"), name, NULL, _MAX_PATH, fname, &dum) == 0)
return FALSE;
if (mch_isdir(fname))
return FALSE;


--
- Yasuhiro Matsumoto

Yasuhiro MATSUMOTO

unread,
Jan 30, 2009, 1:17:28 AM1/30/09
to vim...@vim.org, Bram Moolenaar
oops.

---------------------


function executable() is too slow on windows. it seems that using
SearchPath() API.

SearchPath() tries following sequence if lpPath was set NULL.
---------------------

--
- Yasuhiro Matsumoto

Yasuhiro MATSUMOTO

unread,
Jan 30, 2009, 1:43:44 AM1/30/09
to vim...@vim.org, Bram Moolenaar
Hmm. current directory was skipped with my patch.

--
- Yasuhiro Matsumoto

Yasuhiro MATSUMOTO

unread,
Jan 30, 2009, 2:18:28 AM1/30/09
to vim...@vim.org, Bram Moolenaar
I wrote new patch. however it took delay time nearly same as no patched. X-(

BTW)
I have which.exe command line program which is downloaded on
http://gnuwin32.sf.net.
It is better faster than executable(). maybe it does not use SearchPath() API.


Index: src/os_win32.c
===================================================================
--- src/os_win32.c (revision 1341)
+++ src/os_win32.c (working copy)
@@ -1583,6 +1583,8 @@
{
char *dum;
char fname[_MAX_PATH];
+ char *path, *newpath;
+ long n;

#ifdef FEAT_MBYTE
if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
@@ -1590,11 +1592,18 @@
WCHAR *p = enc_to_utf16(name, NULL);
WCHAR fnamew[_MAX_PATH];
WCHAR *dumw;
- long n;
+ WCHAR *wpath, *wnewpath;

if (p != NULL)
{
- n = (long)SearchPathW(NULL, p, NULL, _MAX_PATH, fnamew, &dumw);

+ wpath = _wgetenv(L"PATH");
+ wnewpath = (WCHAR*)alloc((unsigned)(wcslen(wpath) + 4) * sizeof(WCHAR));
+ if (wnewpath == NULL)
+ return FALSE;
+ wcscpy(wnewpath, L";.;");
+ wcscat(wnewpath, wpath);
+ n = (long)SearchPathW(wnewpath, p, NULL, _MAX_PATH, fnamew, &dumw);
+ vim_free(wnewpath);


vim_free(p);
if (n > 0 || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
{

@@ -1608,8 +1617,17 @@


}
}
#endif
- if (SearchPath(NULL, name, NULL, _MAX_PATH, fname, &dum) == 0)
+

+ path = getenv("PATH");
+ newpath = (char*)alloc((unsigned)(STRLEN(path) + 4));
+ if (newpath == NULL)
return FALSE;
+ STRCPY(newpath, ";.;");
+ STRCAT(newpath, path);
+ n = (long)SearchPath(newpath, name, NULL, _MAX_PATH, fname, &dum);
+ vim_free(newpath);
+ if (n == 0)
+ return FALSE;
if (mch_isdir(fname))
return FALSE;
return TRUE;

mattn

unread,
Aug 26, 2014, 6:53:26 AM8/26/14
to vim...@googlegroups.com, vim...@vim.org, Br...@moolenaar.net
Hi bram

I got a report: exepath() return wrong value. So I updated this patch.

https://gist.github.com/mattn/4d94e093bb777f79c444

When first argument is set as NULL, SearchPath() works to search windows directory before PATH environment. So "C:\Windows\System32\counvert.exe" will be found even though PATH contains imagemagick directory at the first.

Please check.
- Yasuhiro Matsumoto

Bram Moolenaar

unread,
Aug 26, 2014, 4:32:43 PM8/26/14
to mattn, vim...@vim.org, Br...@moolenaar.net
Thanks. Does this work well on all kinds of Windows systems?

--
hundred-and-one symptoms of being an internet addict:
74. Your most erotic dreams are about cybersex

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

mattn

unread,
Aug 26, 2014, 8:54:24 PM8/26/14
to vim...@googlegroups.com, matt...@gmail.com, vim...@vim.org, Br...@moolenaar.net
Ah, sorry.

This is wrong. Because current directory must be contained in the search paths. system() or ":!" works with current directory. So ignore above reply.

Please use patch older or look newer patch that k_takata modified for new version of vim.

https://12985092515833507022.googlegroups.com/attach/7c3ae21f1b36721b/searchpath.patch?part=0.1&view=1&vt=ANaJVrHv5R2-Hk-rI2lEhEfEpSyuFMm9FK0e1TP5wg6MgB41sKqkMhGvLvBx2cI2GZH-sXFTlqNBxYGyUcT6SUZ3_KMWLBASyj-fVFBTTNFMvbkUlsuGIbc

But some users seems to have a hard time to debug this. So please merge this.

- Yasuhiro Matsumoto


Reply all
Reply to author
Forward
0 new messages