[Haskell-cafe] How to optimize a directory scanning?
Neil Mayhew
neil_mayhew at users.sourceforge.net
Fri May 10 17:12:47 UTC 2019
It would be possible to avoid that TCGETS ioctl since the immediately
preceding fstat shows that the file is a regular file and not a device.
However, I'm not sure how easy it would be for the library to make that
optimization.
The Haskell implementation actually makes less syscalls than the Rust
one, because Rust reads the file in very small chunks (32,32,64,128,64)
whereas Haskell reads one big chunk (8192) which is sufficient to
contain the entire file. I think it's unlikely that the extra ioctl
outweighs the multiple extra reads. However, if you use the -r option
with strace to include timestamps in the output, you'll be able to see
just how long each syscall is taking. On my system, they all take about
the same amount of time.
It would also be worth using time on the program, to see how much of the
CPU time is in user space vs kernel.
On 2019-05-10 9:35 AM, Brandon Allbery wrote:
> The ioctl is standard, including in C unless you are using open()
> directly: it checks to see if the opened file is a terminal, to
> determine whether to set block or line buffering.
>
> On Fri, May 10, 2019 at 11:09 AM Magicloud Magiclouds
> <magicloud.magiclouds at gmail.com
> <mailto:magicloud.magiclouds at gmail.com>> wrote:
>
> So this is what I got. Seems like both calls two stat(stat/newfstatat)
> for dir checking and uid checking. But when open file for reading,
> there is an ioctl call (maybe from System.IO.Strict) which seems
> failed, for Haskell. I want to test the case without System.IO.Strict.
> But have no idea how to get exception catching works with lazy
> readFIle.
>
> For Haskell implenmentation,
> ```
> stat("/proc/230", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
> stat("/proc/230", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
> openat(AT_FDCWD, "/proc/230/stat", O_RDONLY|O_NOCTTY|O_NONBLOCK) = 23
> fstat(23, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
> ioctl(23, TCGETS, 0x7ffe88c18090) = -1 ENOTTY (Inappropriate
> ioctl for device)
> read(23, "230 (scsi_eh_5) S 2 0 0 0 -1 212"..., 8192) = 155
> read(23, "", 8192) = 0
> close(23)
> ```
> For Rust implenmentation,
> ```
> newfstatat(3, "1121", {st_mode=S_IFDIR|0555, st_size=0, ...},
> AT_SYMLINK_NOFOLLOW) = 0
> stat("/proc/1121", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
> open("/proc/1121/stat", O_RDONLY|O_CLOEXEC) = 4
> fcntl(4, F_SETFD, FD_CLOEXEC) = 0
> fstat(4, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
> read(4, "1121 (ibus-engine-sim) S 1077 10", 32) = 32
> read(4, "77 1077 0 -1 4194304 425 0 1 0 5", 32) = 32
> read(4, "866 1689 0 0 20 0 3 0 3490 16454"..., 64) = 64
> read(4, "4885264596992 94885264603013 140"..., 128) = 128
> read(4, "0724521155542 140724521155575 14"..., 256) = 64
> read(4, "", 192) = 0
> close(4)
> ```
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20190510/c073062e/attachment.html>
More information about the Haskell-Cafe
mailing list