您當前的位置:首頁 > 收藏

為什麼 Windows 比 Linux 的檔案搜尋慢很多?

作者:由 豆豆漿 發表于 收藏時間:2018-07-19

為什麼 Windows 比 Linux 的檔案搜尋慢很多?知乎使用者2022-04-11 01:15:50

問題是,你在 Linux 下是怎麼“搜尋”的呢。

locate 是預先建立索引的。Mac 下的 Spotlight 也是。

find 的話,也沒比 Windows 快到哪去啊。

你有可供比較的資料嗎?

為什麼 Windows 比 Linux 的檔案搜尋慢很多?北極2022-04-11 04:18:22

先說結論,

Windows檔案系統的效能就是要比Linux慢

,這是一個事實。我做過Windows的檔案系統開發(寫檔案系統),也研究過Linux檔案系統,還做過UNIX-like的檔案系統的設計和開發,Windows的檔案系統在各個方面效能都不如Linux。

題主這個問題分兩部分回答:

一、應用軟體搜尋慢

Windows在檔案系統裡搜尋的時候,會搜尋一部分檔案內容,會展開搜尋一部分壓縮包(比如CAB檔案)的內容,並不是只搜尋檔名,所以搜尋負擔更重(要開啟檔案並讀取內容)。而開始選單裡(也就是題主說的左下角)搜尋是基於預先建立的索引,所以更快一些。

這本質上是軟體設計的問題,Windows如果用其它搜尋工具,比如everything等,搜尋速度是比自帶的搜尋要快一些的。但Windows native API仍然比不過Linux,所以才有第二部分。

二、檔案系統訪問慢

為了證明這一點,我專門做了一個實現,分別在Windows和Linux平臺寫兩個最簡單的遞迴列舉目錄的程式碼,Windows使用FindNextFile(),Linux使用readdir(),遞迴列舉一個目錄樹,然後計算時間。其中Windows程式碼是直接執行的,Linux是Ubuntu 20。04

執行在虛擬機器裡

。關閉所有防毒軟體和可能影響效能的軟體。

被測的目標目錄是VirtualBox6。1。32的原始碼包含4萬多個檔案和目錄,總大小1G多,Windows和Linux虛擬機器都在同一個磁碟上,儲存介質速度是一致的(準確的說Linux會更慢,因為是虛擬機器)。

開機首輪測試

第二次

第三次

Windows

6868 ms

197 ms

195 ms

Linux虛擬機器

248 ms

52 ms

64 ms

可以看到不管是無cache(開機首輪測試)還是有cache的情況下,Windows的檔案系統性能都遠不如Linux,所以Windows檔案系統慢是一個事實,而不僅僅只是使用者感覺。

慢的原因有多方面的,可以透過分析Linux程式碼和Windows的原始碼(基於WinXP洩漏的原始碼,還有WRK)來得到結論:

1. Windows的列舉目錄項的操作效率太低。

因為讀目錄每次都要經過一次系統呼叫,所以不管是Windows還是Linux都在設計上儘量減少系統呼叫的次數。

Windows提供的FindNextFileW這個API,每次透過函式NtQueryDirectoryFile最後經系統呼叫到檔案系統驅動,獲得目錄內的子檔案資訊,為了減少系統呼叫次數,NtQueryDirectoryFile一次可以獲得多個子檔案資訊,放到一個快取裡,這個快取的大小是4K:

#define FIND_BUFFER_SIZE 4096

Linux提供的readdir()裡也有類似的動作,Linux的預設快取是BUFSIZ * 4,定義如下(位於glibc):

#define BUFSIZ 8192

也就是說

Linux的預設快取是Windows的8倍大小

,從直觀上就可以看出Linux一次系統呼叫能獲取的子檔案專案更多。

同樣是獲取4萬多個檔案資訊,Windows需要的系統呼叫要比Linux多。系統呼叫對於作業系統來說是一個巨大的開銷,Windows比Linux要慢,大部分原因都是因為系統呼叫太多導致的。

2. Windows目錄資訊比Linux要多。

Windows檔案系統裡有個

短名

的概念,並且Windows預設是UTF-16的編碼

,所以同樣一個英文字串檔名,Linux要比Windows少至少一半的資料

Windows:

typedef

struct

_WIN32_FIND_DATAW

{

DWORD

dwFileAttributes

FILETIME

ftCreationTime

FILETIME

ftLastAccessTime

FILETIME

ftLastWriteTime

DWORD

nFileSizeHigh

DWORD

nFileSizeLow

DWORD

dwReserved0

DWORD

dwReserved1

WCHAR

cFileName

MAX_PATH

];

WCHAR

cAlternateFileName

14

];

}

WIN32_FIND_DATAW

*

PWIN32_FIND_DATAW

*

LPWIN32_FIND_DATAW

Linux:

struct

dirent

{

#ifdef __USE_FILE_OFFSET64

__ino64_t

d_ino

#else

__ino_t

d_ino

int

__pad

#endif

__off_t

d_off

unsigned

short

int

d_reclen

unsigned

char

d_type

char

d_name

256

];

/* We must not include limits。h! */

};

另外,因為Windows一個檔案有兩個名字:長名和短名,所以Windows的name cache比Linux更復雜,需要更多的記憶體,

同一個檔案需要兩個名位元組點

,也間接導致了檔案系統查詢名字的效率更低。

Windows檔案系統內部用的是Unicode,如果用FindNextFileA的話,效能比Unicode版本還慢,因為FindNextFileA呼叫的是FindNextFileW並且還多了一個字符集轉換。

3. Windows快取機制不夠激進

Linux系統啟動以後,一般會先劃分走一半的物理記憶體作為快取,但Windows一直以來都沒有這麼激進的快取策略,所以Linux檔案系統快取效率會比Windows要高,效能也高很多。

4. 其它原因

Windows檔案系統效率低還有很多細節的原因,比如Windows核心的通知機制更長更復雜(尤其表現在刪除檔案效能上)。

Windows安全檢查比較多並且複雜(NTFS許可權比POSIX許可權要多)。

……

所以,上面的幾個共同的原因導致了Windows檔案系統性能比Linux低,操作檔案的效能自然也就比Linux要慢(並且是慢的多了)。

最後,Windows檔案系統訪問慢,是程式碼的問題,不是NTFS的問題,有興趣的同學可以試試在Linux下使用NTFS,你

會發現Linux的NTFS比Windows的還快一些

Windows遞迴列舉目錄的程式碼:

#define _CRT_SECURE_NO_WARNINGS

#include

#include

#include

int

TotalFiles

int

TotalDirectories

void

SearchDirectory

LPCTSTR

lpPath

{

TCHAR

FindDir

MAX_PATH

=

{

0

};

TCHAR

SubDir

MAX_PATH

=

{

0

};

WIN32_FIND_DATA

FindFileData

BOOL

bRet

wcscpy

FindDir

lpPath

);

wcscat

FindDir

L

\\

*。*”

);

HANDLE

hFind

=

FindFirstFile

FindDir

&

FindFileData

);

if

INVALID_HANDLE_VALUE

==

hFind

{

return

}

bRet

=

TRUE

while

bRet

==

TRUE

{

if

wcscmp

FindFileData

cFileName

L

“。”

!=

0

&&

wcscmp

FindFileData

cFileName

L

“。。”

!=

0

{

if

FindFileData

dwFileAttributes

&

FILE_ATTRIBUTE_DIRECTORY

{

TotalDirectories

++

wcscpy

SubDir

lpPath

);

wcscat

SubDir

L

\\

);

wcscat

SubDir

FindFileData

cFileName

);

SearchDirectory

SubDir

);

}

else

{

TotalFiles

++

}

}

bRet

=

FindNextFile

hFind

&

FindFileData

);

}

FindClose

hFind

);

}

int

main

int

argc

char

*

argv

[])

{

LARGE_INTEGER

Freq

Start

End

TCHAR

Path

MAX_PATH

];

MultiByteToWideChar

CP_ACP

0

argv

1

],

strlen

argv

1

])

+

1

Path

sizeof

Path

));

QueryPerformanceFrequency

&

Freq

);

QueryPerformanceCounter

&

Start

);

SearchDirectory

Path

);

QueryPerformanceCounter

&

End

);

printf

“Total Files [%d] Total Directories [%d]

\n

TotalFiles

TotalDirectories

);

printf

“Counter [%lld] Freq [%lld], Total [%lld] ms

\n

End

QuadPart

-

Start

QuadPart

Freq

QuadPart

End

QuadPart

-

Start

QuadPart

*

1000

/

Freq

QuadPart

);

return

0

}

Linux列舉子目錄的程式碼:

#include

#include

#include

#include

#include

int

TotalFiles

int

TotalDirectories

int

SearchDirectory

char

*

path

{

DIR

*

dirfd

struct

dirent

*

entry

char

subpath

256

];

dirfd

=

opendir

path

);

while

((

entry

=

readdir

dirfd

))

!=

NULL

{

strcpy

subpath

path

);

strcat

subpath

“/”

);

strcat

subpath

entry

->

d_name

);

if

strcmp

entry

->

d_name

“。”

!=

0

&&

strcmp

entry

->

d_name

“。。”

!=

0

{

if

entry

->

d_type

==

DT_DIR

{

TotalDirectories

++

SearchDirectory

subpath

);

}

else

{

TotalFiles

++

}

}

}

closedir

dirfd

);

return

0

}

int

main

int

argc

char

*

argv

[])

{

time_t

st

ed

st

=

clock

();

SearchDirectory

argv

1

]);

ed

=

clock

();

printf

“Total Files [%d] Total Directories [%d]

\n

TotalFiles

TotalDirectories

);

printf

“Counter [%ld] Freq [%ld], Total [%ld] ms

\n

ed

-

st

CLOCKS_PER_SEC

ed

-

st

*

1000

/

CLOCKS_PER_SEC

);

return

0

}

輸出

為什麼 Windows 比 Linux 的檔案搜尋慢很多?

為什麼 Windows 比 Linux 的檔案搜尋慢很多?陳炳好2022-04-11 08:51:50

你可以使用everything搜尋,全盤建立索引只需3秒,全盤搜尋0。01秒出結果,即輸即所得。

voidtools

這個軟體的速度,絕對遠超linux的檔案搜尋。

硬體佔用極低

,硬碟讀寫小於0。1M/s,CPU佔用小於0。1%,同時一秒鐘可以索引100萬檔案,支援百萬檔案的毫秒級排序,支援顯示資料夾大小。

為什麼 Windows 比 Linux 的檔案搜尋慢很多?jack zhang2022-04-11 22:06:39

因為windows搜尋檔案,預設是會檢索檔案內容的,這是最耗費時間的。

如果你不檢索檔案內容,可以非常快,例用系統的api,只要檔名,百萬條檔案只要3-5秒左右,這還是機械硬碟。固態硬碟更快。

如果你直接檢索檔案分配表,可以更快。

主要的區別就是windows搜尋檔案,預設會檢索檔案內容。

為什麼 Windows 比 Linux 的檔案搜尋慢很多?Strawing Lee2022-05-01 08:17:33

慢?

我還在為Linux下沒有Everything這樣的工具苦惱呢

標簽: Windows  Linux  檔案系統  檔案  搜尋