<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/62210>62210</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Looking for includes is very slow on windows
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          avudnez
      </td>
    </tr>
</table>

<pre>
    Hi,

I am working on games based on unreal engine, for which we want to use `clang-cl` to compile on windows.
It works fine, but the performance is very bad during preprocessing. This is particularly noticeable when using FASTBuild with distribution, because it starts by preprocessing all sources before sending them to be compiled remotely.

The performance hit comes from NTFS' minifilter drivers that hook themselves on many filesystem operations, and can cause huge slowdowns when they are badly implemented (for example, sharing a system-global lock on any file operation inside the driver).
I've profiled this using WPA / https://github.com/google/UIforETW and found multiple minifilters slowing our preprocessing step by up to x10.

This is especially problematic on large projects such as unreal engine, that have a huge number of includes multiplied by a huge number of include paths.

Qt people noticed the same thing with their `moc` tool : https://bugreports.qt.io/browse/QTBUG-81348 and suggested 
> Since moc and the compiler must both satisfy #include declarations, I wondered why the msvc compiler (cl.exe) was able to do so faster and without being impacted by bindflt. I collected sampling data from cl.exe during a build and it appears that the `cl.exe::CheckFileExists` function makes many calls to the Windows API function [ZWQueryDirectoryFile](https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-zwquerydirectoryfile). My guess is that the file system is able to quickly check for the existence of a file when given a handle to the directory and a leaf file name but is much slower to return when `GetFileAttributesEx` is called, since the later presumably requires the file system to walk down the path from the root to the leaf.

`GetFileAttributesEx` is not called by clang, but `CreateFileW` is and I guess this is similar because the result is the same.
Here's a (partial) sample callstack from WPA showing that clang is spending almost all its execution time inside `CreateFileW`.

Line # | Process | Thread Name | Thread ID | Stack | Count | Weight (in view) (ms)
-- | -- | -- | -- | -- | -- | --
35 | Â  | Â  | Â  | clang-cl.exe!<Missing ImageId event> | 11477 | 11 477,857900
36 | Â  | Â  | Â  | KernelBase.dll!CreateFileW | 8982 | 8 982,562700
37 | Â  | Â  | Â  | KernelBase.dll!CreateFileInternal | 8979 | 8 979,563000
38 | Â  | Â  | Â  | ntdll.dll!NtCreateFile | 8786 | 8 786,541700
39 | Â  | Â  | Â  | ntoskrnl.exe!KiSystemServiceCopyEnd | 8766 | 8 766,537700
40 | Â  | Â  | Â  | ntoskrnl.exe!NtCreateFile | 8766 | 8 766,537700
41 | Â  | Â  | Â  | ntoskrnl.exe!IopCreateFile | 8765 | 8 765,537500
42 | Â  | Â  | Â  | ntoskrnl.exe!ObOpenObjectByNameEx | 8733 | 8 733,536900
43 | Â  | Â  | Â  | ntoskrnl.exe!ObpLookupObjectName | 8670 | 8 670,522100
44 | Â  | Â  | Â  | ntoskrnl.exe!IopParseFile | 4780 | 4 780,235200
45 | Â  | Â  | Â  | ntoskrnl.exe!IopParseDevice | 4775 | 4 775,234100
46 | Â  | Â  | Â  | ntoskrnl.exe!IoCallDriverWithTracing | 4611 | 4 611,223300
47 | Â  | Â  | Â  | ntoskrnl.exe!IofCallDriver | 4611 | 4 611,223300
48 | Â  | Â  | Â  | FLTMGR.SYS!FltpCreate | 4608 | 4 608,222600
49 | Â  | Â  | Â  | FLTMGR.SYS!FltpPassThroughInternal | 3543 | 3 543,174700
50 | Â  | Â  | Â  | FLTMGR.SYS!FltpPerformPreCallbacksWorker | 3540 | 3 540,175500
51 | Â  | Â  | Â  | bindflt.sys!BfPreCreate | 2079 | 2 079,083900
52 | Â  | Â  | Â  | fileinfo.sys!FIPreCreateCallback | 1271 | 1 271,075700

I don't have symbols for clang right now so I'm still not sure what the code path leading to this is, but I hope it helps.

If someone could provide pointers, I might be able to investigate this more and try patches on my setup.

Thanks
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykmE1zozrWgH8N2ZyKC4QxeJFF4sR9Xbc_0m9yK_XOTsDBaCwkWhJ2fH_91JGwHSd9e1w9m0RgSc_5PhLcWrFWiDdRdhdl91d8cK02N3w71Ar_vip1vb_5Q0RsEcX3UXwb_q6Ad7DTZiPUGrSCNe_QQskt1vQ4KINcAqq1UBixBTTawK4VVQs7hB1XDpyGwSJEs7iSXK2vKxnNYnpb6a4XEmmbnVC13tnJyHSeaKEZNy0HB65F6NE02nRcVQjCwhbNHkpeQz0YEq832BtdobVCrSfw3ApL03punKgGyY3cg9JOVMhLibBrUcFAc2F5-_R8NwhZw064FmphnRHl4IRWno8VJx2EA-u4cRbK_TkNuJRg9WAqsg422iBYVDX95FrsSN8SDyrXYLDTDuV-8tbWz-9UbIWjFWihMbqDr8_Lp4jl0AklGiEdGqiN2KKx4FruoNV642EW5RYt2bXjag-NkGj31mEHukfDSStLanFVQ8UVBOXaYY1gpd7VeqdssI5rcQ_cIFlZ7kF0vcQOlcMaIlaQr_GV00vazrbcu4FDoF2vpS65BKmrDQlzkOUkBQhlRY3et0GViM0PQRCxfIvQG914iznyZvDWy-MtRGwJrXO9jdLbiC0jtlwL1w7lpNIdPWi9JqmWf60abR6eX7yyjR5UDd0gneglvjGk9Yr7EB_MO89ahz35e-jJia9J_M5nIcjQ9lgJLiUFhi4ldtyJitSW3Ky9Hv_GylmwQ9UCtx8zJ_iQbxF48IUauhIN6AaEquRQoz2ILrAmif5pHvTctfZMzO8OetSkdEiA2tvc8o6MT1r6uHctCkOZ2ukqJKmWEKW37yxdDmuDvTbOTn64idD0yuidJXt_f77769N1kaTTwpvcDus1Wh8wQZz0AZ4ERXenKz-DBBnzwkA3WAeldi1Y7oRt9hCx9KBWjZXkb-J3BTutajRYw67d-406u61Ou0WsqOQEXzFic9hxCz7vnYZag9XQcEtJREKQ-npwUCIZQ3Q9r1wwcilU3Ug3gRVUWkr07y0FPc2sueMhOwPoUIo4lL6c0N7CAe975Ic8JTl9NfSSpbdRertosdoshcSHV2GdJds3g6p8jnR8Q56n7Km4lJbkpy1eQs2E28fVaXKU3f3r5fuAZn8vDFZOmz1tG2X3ESvOvVjryk46URltdePGvEF1PdiILceCfN1yU--4Ic-OtYZGtYjYUjnR0JNqrv3w-u_dDwLXBzDlLeUzfNnDekDr8-RoAV8JxrIkTp75MYhqI_dQkUV8N6HJSGZBihrdAA9rfYFaiy0qSgSu6rCBryUHEbz9OUjkTVikKOKpnQhKpqr1eY-GFhp0g1Fh22gWf0JHlrt1oROgfXgltwjrvYC1r3g-kIkoOUVSb9AOHS_lHgz-GIRB-0FXp2HH5Qaoyoamxl0bQoiejNbuoAaJfZbFvxRLaTeKRmHre-2hd0azeGGQO6SlL-N8Ms1qdIwbq5gVnZDcHBuelwjtIF3wXSgZo0x_IMVFboFTovkuyyVlms8ODNHqOLmRtKOqbdtQZX0UeBE9tR87JZedts73UuEs4CtWvgeDEx0emsUHZc5M9FkopJoBUb6Ax1DF_fi5Nchr-EoB8OZ5de-fnrycNFroQTk_ekGxbh3pJhRsBe5It4gVnY3YPNCur_3Mi_6FFWnmH6MFi27jXwwPZ6VQvZIoXXwRoR-tOr7GVQ24ReWonNL0JJnm-TgKu0zzPGKLIsvncTyiZ5eh_0SjUN5xi5Nayoglb8ztJxTzgoVBWDUvWMQW2YzlR1T-P6NWyqFRXI7EfH5GzOeemMZHYnEZUblayhH21Z1wYfe8mL3F5MWMMNPkpNj8Uoy2G6MO7vtTPPnsf0KzFRUudL9_UPXInJ0zZ56Z5kfm9Feg0zCM3oF_ouJ_xSW_peJK9x9R2TkqC6jsiGK_hfpWfutRfSvpQHW3p4x-eB2JaXpGTFNPnB1zYJr-JrH_rPVm6AP0WESKWR6_Bc7ymICMJUfg9Het-ciNPRlzmhdh4vQQmkRiacaOpAsryz-Q7pEic2Tl2RkrzzxretLqwlLygbXgUt77g8SLcO2z4RWVNM-aJclb6CxJCMrS9Ai9rKj8NA9WujmhL-VdWFKWn5-_fPq_ydP_P0UsWUo35sFIiYszSlx4CpsdKRdWlA-UR27tc2v0sG7PamWajUGehtXZlJIgyafHDM8uKyg_QYbL6aNBMmbJq4190WYzWjTNxkp1BMcenB3zPbuwtBzO3HZvI5bcNQQ82ZTFYzNgYUnsm0FcpMcszy6sK3QuE6rRI2i5OoIO-oWWyvIg-NhaWU6hEufZ0aKHbyW1VhHLx2uc3XelltYfYsNZx_gDhdI7un3QBbcD64SU_uxmB0OH2vF4XOnxHkenwPAZQR-OaYdj3Qpa3fuvEi3K_vzCt2rA6g61oq0GWdMFdEvHp14LipbxAtV5iUo8nr-F2qJ1Yk3G9rhOGwz3NLMngap2_LSwB4tu6N_dhrna2Kv6Jq3n6Zxf4U0yK5KCzdh0ftXeNCyez5u6ajAtyqLJE55jkk-LOMviMinwStywmKXxNCmSNMvZfMLqCuOYz-K8SfKiYdE0xo4LOZFy2020WV8Jawe8mVHJvZK8RGn99y3GFO7A_xgxFmX3V-aG1lyXw9pG01jSPeu0ixNO4g3VeDI1eex45z58aKKbwptvVVeDkTe_-AJBW4__rsfLf8SWXiC6NXmB_xMAAP__hqLwDQ">