summaryrefslogtreecommitdiff
path: root/src/lib/eina
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2019-05-07 11:07:19 +0100
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2019-05-07 11:15:54 +0100
commit770cede2bf925b49f7738daa0598260ce183293c (patch)
treeb313d02ff0043f1edea17f9838d8aa0ff1fbf0f1 /src/lib/eina
parent6d78454142d371520f850f69782c690f9fbc735b (diff)
eina_file: speed up listing of directories on Windows
Summary: forbid the creation of short name (legacy of DOS) Without optimisation 1. using only Win32 API, just iterating over directories (in micro seconds) : 10 files : 47 1000 files : 270 100000 files : 73227 2. using eina_file_dir_list() with a callback which does nothing : 10 files : 53 1000 files : 265 100000 files : 69624 usually there is a small overhead for eina API, which is normal With optimisation 1. using only Win32 API, just iterating over directories (in micro seconds) : 10 files : 51 1000 files : 256 100000 files : 33345 2. using eina_file_dir_list() with a callback which does nothing : 10 files : 53 1000 files : 251 100000 files : 33832 speed up with 1000 files and more. Twice faster with 100000 files Test Plan: benchmark program Reviewers: raster, cedric, zmike Subscribers: #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8842
Diffstat (limited to 'src/lib/eina')
-rw-r--r--src/lib/eina/eina_file_win32.c64
1 files changed, 21 insertions, 43 deletions
diff --git a/src/lib/eina/eina_file_win32.c b/src/lib/eina/eina_file_win32.c
index 7ed6d03..e10a8f5 100644
--- a/src/lib/eina/eina_file_win32.c
+++ b/src/lib/eina/eina_file_win32.c
@@ -117,39 +117,32 @@ _eina_file_win32_is_dir(const char *dir)
117 return EINA_TRUE; 117 return EINA_TRUE;
118} 118}
119 119
120static char *
121_eina_file_win32_dir_new(const char *dir)
122{
123 char *new_dir;
124 size_t length;
125
126 length = strlen(dir);
127
128 new_dir = (char *)malloc(sizeof(char) * length + 5);
129 if (!new_dir)
130 return NULL;
131
132 memcpy(new_dir, dir, length);
133 memcpy(new_dir + length, "\\*.*", 5);
134
135 return new_dir;
136}
137
138static HANDLE 120static HANDLE
139_eina_file_win32_first_file(const char *dir, WIN32_FIND_DATA *fd) 121_eina_file_win32_first_file(const char *dir, WIN32_FIND_DATA *fd)
140{ 122{
141 HANDLE h; 123 char buf[4096];
124 HANDLE h;
125 size_t l = strlen(dir);
142#ifdef UNICODE 126#ifdef UNICODE
143 wchar_t *wdir = NULL; 127 wchar_t *wdir = NULL;
128#endif
144 129
145 wdir = evil_char_to_wchar(dir); 130 l = strlen(dir);
131 if ((l + 5) > sizeof(buf))
132 return INVALID_HANDLE_VALUE;
133
134 memcpy(buf, dir, l);
135 memcpy(buf + l, "\\*.*", 5);
136
137#ifdef UNICODE
138 wdir = evil_char_to_wchar(buf);
146 if (!wdir) 139 if (!wdir)
147 return INVALID_HANDLE_VALUE; 140 return INVALID_HANDLE_VALUE;
148 141
149 h = FindFirstFile(wdir, fd); 142 h = FindFirstFileEx(wdir, FindExInfoBasic, fd, FindExSearchNameMatch, NULL, 0);
150 free(wdir); 143 free(wdir);
151#else 144#else
152 h = FindFirstFile(dir, fd); 145 h = FindFirstFileEx(buf, FindExInfoBasic, fd, FindExSearchNameMatch, NULL, 0);
153#endif 146#endif
154 147
155 if (!h) 148 if (!h)
@@ -469,7 +462,6 @@ eina_file_dir_list(const char *dir,
469{ 462{
470 WIN32_FIND_DATA file; 463 WIN32_FIND_DATA file;
471 HANDLE h; 464 HANDLE h;
472 char *new_dir;
473 465
474 EINA_SAFETY_ON_NULL_RETURN_VAL(cb, EINA_FALSE); 466 EINA_SAFETY_ON_NULL_RETURN_VAL(cb, EINA_FALSE);
475 EINA_SAFETY_ON_NULL_RETURN_VAL(dir, EINA_FALSE); 467 EINA_SAFETY_ON_NULL_RETURN_VAL(dir, EINA_FALSE);
@@ -478,11 +470,7 @@ eina_file_dir_list(const char *dir,
478 if (!_eina_file_win32_is_dir(dir)) 470 if (!_eina_file_win32_is_dir(dir))
479 return EINA_FALSE; 471 return EINA_FALSE;
480 472
481 new_dir = _eina_file_win32_dir_new(dir); 473 h = _eina_file_win32_first_file(dir, &file);
482 if (!new_dir)
483 return EINA_FALSE;
484
485 h = _eina_file_win32_first_file(new_dir, &file);
486 474
487 if (h == INVALID_HANDLE_VALUE) 475 if (h == INVALID_HANDLE_VALUE)
488 return EINA_FALSE; 476 return EINA_FALSE;
@@ -496,7 +484,9 @@ eina_file_dir_list(const char *dir,
496# else 484# else
497 filename = file.cFileName; 485 filename = file.cFileName;
498# endif /* ! UNICODE */ 486# endif /* ! UNICODE */
499 if (!strcmp(filename, ".") || !strcmp(filename, "..")) 487 if ((filename[0] == '.') &&
488 ((filename[1] == '\0') ||
489 ((filename[1] == '.') && (filename[2] == '\0'))))
500 continue; 490 continue;
501 491
502 cb(filename, dir, data); 492 cb(filename, dir, data);
@@ -563,7 +553,6 @@ EAPI Eina_Iterator *
563eina_file_ls(const char *dir) 553eina_file_ls(const char *dir)
564{ 554{
565 Eina_File_Iterator *it; 555 Eina_File_Iterator *it;
566 char *new_dir;
567 size_t length; 556 size_t length;
568 557
569 EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL); 558 EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL);
@@ -582,12 +571,7 @@ eina_file_ls(const char *dir)
582 571
583 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); 572 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
584 573
585 new_dir = _eina_file_win32_dir_new(dir); 574 it->handle = _eina_file_win32_first_file(dir, &it->data);
586 if (!new_dir)
587 goto free_it;
588
589 it->handle = _eina_file_win32_first_file(new_dir, &it->data);
590 free(new_dir);
591 if ((it->handle == INVALID_HANDLE_VALUE) && (GetLastError() != ERROR_NO_MORE_FILES)) 575 if ((it->handle == INVALID_HANDLE_VALUE) && (GetLastError() != ERROR_NO_MORE_FILES))
592 goto free_it; 576 goto free_it;
593 577
@@ -614,7 +598,6 @@ EAPI Eina_Iterator *
614eina_file_direct_ls(const char *dir) 598eina_file_direct_ls(const char *dir)
615{ 599{
616 Eina_File_Direct_Iterator *it; 600 Eina_File_Direct_Iterator *it;
617 char *new_dir;
618 size_t length; 601 size_t length;
619 602
620 EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL); 603 EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL);
@@ -633,12 +616,7 @@ eina_file_direct_ls(const char *dir)
633 616
634 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); 617 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
635 618
636 new_dir = _eina_file_win32_dir_new(dir); 619 it->handle = _eina_file_win32_first_file(dir, &it->data);
637 if (!new_dir)
638 goto free_it;
639
640 it->handle = _eina_file_win32_first_file(new_dir, &it->data);
641 free(new_dir);
642 if ((it->handle == INVALID_HANDLE_VALUE) && (GetLastError() != ERROR_NO_MORE_FILES)) 620 if ((it->handle == INVALID_HANDLE_VALUE) && (GetLastError() != ERROR_NO_MORE_FILES))
643 goto free_it; 621 goto free_it;
644 622