⌚
ls とls -lの速度比較
はじめに
lsコマンドでファイルやディレクトリの確認をしていますが、-lのオプションをつけると差はどのようになるのでしょうか。気になったので簡単に実験してみました。
マシンスペック
MacBook Air M2 arm64
Docker上で実施
準備
ディレクトリの作成
mkdir -p ~/ls_bench/{build,logs,src}
cd ~/ls_bench
解析用のpythonスクリプトを作成しておきます。
# analyse.py
import json, pandas as pd, matplotlib.pyplot as plt, sys, pathlib
d = json.load(open('/logs/time.json'))
df = pd.DataFrame(d['results'])
df[['command','mean','stddev']].to_csv('/logs/time.csv', index=False)
df.plot.bar(x='command', y='mean', legend=False)
plt.title('Execution time on 10k files')
plt.ylabel('seconds')
plt.tight_layout()
plt.savefig('/logs/time.png')
Dockerfileの作成・ビルド
FROM ubuntu:22.04
RUN apt-get update && DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends \
strace \
perf-tools-unstable \
hyperfine \
build-essential \
git less time \
python3 python3-pip \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /work
COPY analyse.py /work/
docker build -t ls_bench .
docker run --rm -it \
--name ls_lab \
--privileged \
-v "$HOME/ls_bench/logs":/logs \
-v "$HOME/ls_bench/src":/src \
ls_bench /bin/bash
コンテナ内で実験ディレクトリを用意
mkdir -p /tmp/bench/huge && cd /tmp/bench/huge
seq 1 10000 | xargs -I{} touch f_{}
実験
実行時間測定
cd /tmp/bench/huge
hyperfine 'ls' 'ls -l' -w 3 -r 10 \
--export-markdown /logs/time.md \
--export-json /logs/time.json
hyperfine 'ls' 'ls -l' -w 3 -r 10 \
--export-markdown /logs/time.md \
--export-json /logs/time.json
Benchmark 1: ls
Time (mean ± σ): 4.1 ms ± 0.7 ms [User: 2.0 ms, System: 2.1 ms]
Range (min … max): 3.5 ms … 5.8 ms 10 runs
Warning: Command took less than 5 ms to complete. Results might be inaccurate.
Benchmark 2: ls -l
Time (mean ± σ): 19.4 ms ± 1.0 ms [User: 6.6 ms, System: 12.9 ms]
Range (min … max): 18.7 ms … 21.9 ms 10 runs
Summary
'ls' ran
4.73 ± 0.84 times faster than 'ls -l'
straceでsyscallを見る
strace -c -o /logs/ls.raw ls 1>/dev/null
head /logs/ls.raw
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
18.78 0.000694 347 2 getdents64
17.51 0.000647 129 5 read
11.80 0.000436 436 1 execve
10.61 0.000392 65 6 openat
9.85 0.000364 26 14 mmap
5.22 0.000193 24 8 mprotect
4.44 0.000164 82 2 2 statfs
4.44 0.000164 23 7 newfstatat
strace -c -o /logs/ls_l.raw ls -l 1>/dev/null
head /logs/ls_l.raw
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
52.20 0.166379 16 10000 statx
24.88 0.079297 7 10000 10000 lgetxattr
22.00 0.070118 7 10000 10000 getxattr
0.54 0.001715 155 11 getdents64
0.06 0.000199 13 15 close
0.06 0.000177 19 9 read
0.05 0.000166 11 14 newfstatat
0.04 0.000137 34 4 4 connect
Pythonで簡易分析
| command | mean | stddev |
|---|---|---|
| ls | 0.00371396088 | 0.0005009406445877150 |
| ls -l | 0.01786725238 | 0.0006227547928881170 |

まとめ
今回はlsとls-lの比較をしてみました。皆さんの学習の一助になれば幸いです。
Discussion