Getting the hardlink flag takes about 25% of the time to display a fileinfo when doing ls.
Is it really that important? Could it be made optional, or hidden behind some option?
Do p/invoke so slow? On Windows only or on Unix-s too?
I guess windows only.
The slowness comes from having to reopen each file to get the hardlink count. The rest of the information is available in the FileInfo object.
For the hardlink, we need to call CreateFile (slow) to get a handle, and then use it to get the handle info (fast).
cmd.exe doesn't do this. It shows link types when there is a reparse-point. We could display when there is a reparse point, and ignore hardlinks.
The slowness comes from having to reopen each file to get the hardlink count
I wonder that is so slow. In the topic I see " In testing, it slowed down our processing from 240ms for 21000 files, to 750ms. "
We could display when there is a reparse point, and ignore hardlinks.
Agree. But it looks as a breaking change and also we need a way to expose the information by demand (new switch?)
I'm not sure it is a breaking change. If I recall correctly, formatting is explicitly not a part of the public contract.
cmd.exe doesn't do this. It shows link types when there is a reparse-point. We could display when there is a reparse point, and ignore hardlinks.
IIRC a hard link isn't set as a reparse point so having a check on that won't work. I'm unsure as to the speed but you can use FindFirstFileName and FindNextFileName to enumerate all hard links on a file without calling CreateFile. As for what that does internally I have no idea.
Seems two fields is affected - LinkType and Mode.
The problem is the extra roundtrips to disc, since we don't get enough information from the FileInfo. And going from a FileInfo to a filehandle, which is needed to get the the hardlink count, is expensive on windows.
I argue that this info is so rarely needed that paying the price all the time is not motivated.
Here's some pointers to the relevant docs for people interested in looking deeper:
Desc| Comment
-----|-----
GetFileInformationByHandleEx| The API to get extended file info
FILE_INFO_BY_HANDLE_CLASS enumeration|Enum to select info to retrieve
_FILE_STANDARD_INFO structure| The struct for getting the hardlink count
System.IO| Source code for .net FileInfo etc
Interop definitions in corefx| Structs etc used by the framework to get the data from the file system.
@iSazonov I'm not that concerned about the LinkType as it isn't displayed by default.
I'm starting to think that the right solution is just to change the default formatting. We can keep the current as a non-default view.
@powercode Remove mode from default view? I'd vote to follow cmd.exe behavior (exclude hardlynk from the mode)
I'm fine with that too.
@SteveL-MSFT Can you confirm the change?
Will -Force "force" the display of this info? I do have some hardlinks that I'd link to see what they're targeting.
Get-ChildItem's -Force flag is primarily for displaying hidden or system files. I'd be inclined to think... probably not. I believe there was discussion of a separate switch to enable querying this information?
I'd consider -IncludeHardLinks for Get-Item and Get-ChildrenItem.
I would be ok with removing hardlinks by default. A dynamic param for FileSystemProvider may be an ok solution.
@PowerShell/powershell-committee reviewed this and is ok with not having hardlinks in the default view, consider having a different view that would provide it
I agree with @iSazonov on a seperate switch like -IncludeHardLinks or a generic -IncludeLinks since it also needs to adjust the Process Token Privilege on Windows to get the proper LinkType and Target info, per invocation. See #7127
This is already fixed by #8789
Most helpful comment
I would be ok with removing hardlinks by default. A dynamic param for FileSystemProvider may be an ok solution.