Время различных методов рекурсии по каталогам в LinuxPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Время различных методов рекурсии по каталогам в Linux

Сообщение Anonymous »

Я хотел найти наиболее эффективный метод рекурсивного подсчета подкаталогов и файлов и придумал приведенные ниже тесты. Некоторые, кажется, работают, но результаты непоследовательны.
  • Как я могу исправить несогласованность, из-за которой каждый метод приводит к разному количеству каталогов и разному количеству файлов ( но каждый тест должен давать точно такое же количество каталогов и файлов, как и любой другой тест!).
  • Как я могу исправить неработающие тесты, как показано в выводе ниже?
  • Есть ли методы лучше/быстрее/эффективнее, чем ниже?
Думаю, этот пост находится на грани между StackOverflow и SuperUser, но он относится к скрипту, так что я думаю, это и есть в нужном месте.
#!/bin/bash

# Default to home directory if no argument is provided
dir="${1:-$HOME}"

echo "Analyzing directories and files in: $dir"
echo

# Function to time and run a command, and print the count
time_command() {
local description="$1"
local command="$2"
echo "$description"
echo "Running: $command"
start_time=$(date +%s.%N)
result=$(eval "$command")
end_time=$(date +%s.%N)
duration=$(echo "$end_time - $start_time" | bc)
echo "Count: $result"
echo "Time: $duration seconds"
}

# Methods to count directories
dir_methods=(
"Directory Method 1 (find): find '$dir' -type d | wc -l"
"Directory Method 2 (tree): tree -d '$dir' | tail -n 1 | awk '{print \$3}'"
"Directory Method 3 (du): echo 'deprecated: usually around double length of ''find'' command'"
"Directory Method 4 (ls): ls -lR '$dir' | grep '^d' | wc -l"
"Directory Method 5 (bash loop): count=0; for d in \$(find '$dir' -type d); do count=\$((count + 1)); done; echo \$count"
"Directory Method 6 (perl): perl -MFile::Find -le 'find(sub { \$File::Find::dir =~ /\\/ and \$n++ }, \"$dir\"); print \$n'"
"Directory Method 7 (python): python3 -c 'import os; print(sum([len(dirs) for _, dirs, _ in os.walk(\"$dir\")]))'"
)

# Methods to count files
file_methods=(
"File Method 1 (find): find '$dir' -type f | wc -l"
"File Method 2 (tree): tree -fi '$dir' | grep -E '^[├└─] ' | wc -l"
"File Method 3 (ls): ls -lR '$dir' | grep -v '^d' | wc -l"
"File Method 4 (bash loop): count=0; for f in \$(find '$dir' -type f); do count=\$((count + 1)); done; echo \$count"
"File Method 5 (perl): perl -MFile::Find -le 'find(sub { -f and \$n++ }, \"$dir\"); print \$n'"
"File Method 6 (python): python3 -c 'import os; print(sum([len(files) for _, _, files in os.walk(\"$dir\")]))'"
)

# Run and time each directory counting method
echo "Counting directories..."
echo
for method in "${dir_methods[@]}"; do
description="${method%%:*}"
command="${method#*: }"
if [[ "$description" == *"(du)"* ]]; then
echo "$description"
echo "Running: $command"
eval "$command"
else
time_command "$description" "$command"
fi
echo
done

# Run and time each file counting method
echo "Counting files..."
echo
for method in "${file_methods[@]}"; do
description="${method%%:*}"
command="${method#*: }"
time_command "$description" "$command"
echo
done

Ниже приведена реализация вышеизложенного. Как видите, количество найденных каталогов и файлов в каждом случае разное(!), а некоторые тесты явно не работают, поэтому было бы полезно знать, как это исправить.
< pre class="lang-none Prettyprint-override">Analyzing directories and files in: /home/boss

Counting directories...

Directory Method 1 (find)
Running: find '/home/boss' -type d | wc -l
Count: 598844
Time: 11.949245266 seconds

Directory Method 2 (tree)
Running: tree -d '/home/boss' | tail -n 1 | awk '{print $3}'
Count:
Time: 2.776698115 seconds

Directory Method 3 (du)
Running: echo 'deprecated: usually around double length of ''find'' command'
deprecated: usually around double length of find command

Directory Method 4 (ls)
Running: ls -lR '/home/boss' | grep '^d' | wc -l
Count: 64799
Time: 6.522804741 seconds

Directory Method 5 (bash loop)
Running: count=0; for d in $(find '/home/boss' -type d); do count=$((count + 1)); done; echo $count
Count: 604654
Time: 14.693009738 seconds

Directory Method 6 (perl)
Running: perl -MFile::Find -le 'find(sub { $File::Find::dir =~ /\/ and $n++ }, "/home/boss"); print $n'
String found where operator expected (Missing semicolon on previous line?) at -e line 1, at end of line
Unknown regexp modifier "/h" at -e line 1, at end of line
Unknown regexp modifier "/e" at -e line 1, at end of line
Can't find string terminator '"' anywhere before EOF at -e line 1.
Count:
Time: .019156779 seconds

Directory Method 7 (python)
Running: python3 -c 'import os; print(sum([len(dirs) for _, dirs, _ in os.walk("/home/boss")]))'
Count: 599971
Time: 15.013263266 seconds

Counting files...

File Method 1 (find)
Running: find '/home/boss' -type f | wc -l
Count: 5184830
Time: 13.066028457 seconds

File Method 2 (tree)
Running: tree -fi '/home/boss' | grep -E '^[├└─] ' | wc -l
Count: 0
Time: 8.431054237 seconds

File Method 3 (ls)
Running: ls -lR '/home/boss' | grep -v '^d' | wc -l
Count: 767236
Time: 6.593778380 seconds

File Method 4 (bash loop)
Running: count=0; for f in $(find '/home/boss' -type f); do count=$((count + 1)); done; echo $count
Count: 5196437
Time: 40.861512698 seconds

File Method 5 (perl)
Running: perl -MFile::Find -le 'find(sub { -f and $n++ }, "/home/boss"); print $n'
Count: 5186461
Time: 54.353541730 seconds

File Method 6 (python)
Running: python3 -c 'import os; print(sum([len(files) for _, _, files in os.walk("/home/boss")]))'
Count: 5187084
Time: 14.910791357 seconds


Подробнее здесь: https://stackoverflow.com/questions/793 ... s-in-linux
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»