LINUX.ORG.RU
ФорумTalks

[наблюдение] bash vs ELF


0

0

Дело из разряда наблюдений:

andrey@silverblood (~/Programs/test)$ cat test_c.c                   
#include <stdio.h>

char line[1000];

int main()
{
 FILE *fp = fopen("test_file", "r");
 while(!feof(fp))
 {
  fgets(line, sizeof(line), fp);
  printf("%s", line);
 }
 fclose(fp);
}
andrey@silverblood (~/Programs/test)$ cat test_bash.sh                 
#!/bin/bash

while read -r line; do
 echo "$line"
done < test_file
andrey@silverblood (~/Programs/test)$ file test_file 
test_file: ISO-8859 English text
andrey@silverblood (~/Programs/test)$ gcc test_c.c -o test_c         
andrey@silverblood (~/Programs/test)$ time ./test_c > /dev/null      

real    0m0.005s
user    0m0.004s
sys     0m0.001s
andrey@silverblood (~/Programs/test)$ time ./test_bash.sh > /dev/null

real    0m0.751s
user    0m0.194s
sys     0m0.050s
andrey@silverblood (~/Programs/test)$ wc -l test_file 
5330 test_file
andrey@silverblood (~/Programs/test)$


т.е. имеем разницу 751 / 5 ~= 150 раз по производительности при обработке текстовых файлов. А ведь некоторые утилиты - это баш-скрипты, которые работают с текстом...

Ответ на: комментарий от Muromec

>а давай сравним с асмом и удивимся еще больше?

код ффстудию. к тому же я сомневаюсь что между асмом и си будет заметная разница.

generatorglukoff ★★
() автор топика

Во-первых, нужно писать не ./test_bash.sh, а /bin/bash test_bash.sh. Во-вторых, насколько повторяем этот результат? В-третьих, прогони это хотя бы под strace :)

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>Во-первых, нужно писать не ./test_bash.sh, а /bin/bash test_bash.sh.

с какого перепоя?

Muromec ☆☆
()
Ответ на: комментарий от generatorglukoff

>код ффстудию. к тому же я сомневаюсь что между асмом и си будет заметная разница.

я на асме не умею, а маменьку мою просить в час ночи накодить какую-то хню лучше не надо

Muromec ☆☆
()
Ответ на: комментарий от tailgunner

>Во-первых, нужно писать не ./test_bash.sh, а /bin/bash test_bash.sh.

добавить права на исполнение и выучить sha-bang и не писать ничего левого.

>Во-вторых, насколько повторяем этот результат?

повторяем-повторяем =)

>В-третьих, прогони это хотя бы под strace

я знаю, что bash вызвает проги, а си прога использует напрямую глибк. фишка ведь не в этом, а в том, что в баше нельзя _быстро_ построчно обработать текстовый файл. или я ошибаюсь и можно?

generatorglukoff ★★
() автор топика

а может это кто-то не умеет их готовить??

Вместо простого cat какие-то циклы нагородил:)

dilmah ★★★★★
()

ты бы какой-нить алгоритмик всунул, время ИО - это может еще и не самая серьезная задержка

wieker ★★
()
Ответ на: комментарий от dilmah

>Вместо простого cat какие-то циклы нагородил

фишка не в выводе, а именно в написании цикла построчной обработки.

generatorglukoff ★★
() автор топика
Ответ на: комментарий от generatorglukoff

>>Во-первых, нужно писать не ./test_bash.sh, а /bin/bash test_bash.sh.

>добавить права на исполнение и выучить sha-bang и не писать ничего левого.

Это хорошо, что ты умеешь пользоваться she-bang (she, а не sha). Наверное. ты знаешь, как это работает? Ну так подумай, справедливо ли пользоваться этим при сравнении производительности.

> я знаю, что bash вызвает проги

Откуда такая уверенность? И echo, и read должны быть builtin. Как раз именно это и является самым странным - в данном случае баш _не должен_ вызывать ни одной программы.

> в баше нельзя _быстро_ построчно обработать текстовый файл. или я ошибаюсь и можно?

Вообще-то баш не предназначен для обработки текста :) Он предназначен для _вызова хорошо оптимизированных утилит обработки текста_. В частности, cat, как и сказал dilmah.

Но цифры, полученные тобой, выглядят подозрительно, поэтому я сказал про strace (если тебе интересно выяснить причину медленной работы bash, конечно).

tailgunner ★★★★★
()
Ответ на: комментарий от generatorglukoff

> я знаю, что bash вызвает проги, а си прога использует напрямую глибк. фишка ведь не в этом, а в том, что в баше нельзя _быстро_ построчно обработать текстовый файл. или я ошибаюсь и можно?

в данном случае никаких внешних программ не вызывалось; в шелле много builtin'ов

Но как уже сказано -- основное средство повышения скорости -- использовать awk и т.п. -- это полноправная часть шелла, и это то как он был задуман использоваться. Циклы -- это недоразумение.

dilmah ★★★★★
()
Ответ на: комментарий от tailgunner

нормальные цыфры. только что проверил на баше и zsh

Muromec ☆☆
()
Ответ на: комментарий от Muromec

>а потомушто нефиг на баше это делать. есть перлпитонруби итд

ндп.... баш однако жгет

wieker@localhost:~$ time ./py.py > /dev/null

real 0m0.018s
user 0m0.012s
sys 0m0.004s
wieker@localhost:~$ time ./py.py > /dev/null

real 0m0.018s
user 0m0.016s
sys 0m0.000s
wieker@localhost:~$ time ./test.sh > /dev/null

real 0m0.310s
user 0m0.288s
sys 0m0.012s
wieker@localhost:~$ time ./test.sh > /dev/null

real 0m0.307s
user 0m0.284s
sys 0m0.012s
wieker@localhost:~$ time ./test.sh > /dev/null

real 0m0.305s
user 0m0.284s
sys 0m0.020s
wieker@localhost:~$ time ./py.py > /dev/null

real 0m0.018s
user 0m0.012s
sys 0m0.004s
wieker@localhost:~$ time ./test.sh > /dev/null

real 0m0.303s
user 0m0.304s
sys 0m0.000s
wieker@localhost:~$ cat py.py
#!/usr/bin/python
f = open ("file", "r")
lines = f.readlines()
for x in lines:
print x
wieker@localhost:~$ cat test.sh
#!/bin/bash

while read -r line; do
echo "$line"
echo
done < file
wieker@localhost:~$

wieker ★★
()
Ответ на: комментарий от Gharik

тогда распечатаем и подарим столлману, таннебауму и линусу =)

Muromec ☆☆
()

бля... простите за мой французский

Master Foo once said to a visiting programmer: “There is more Unix-nature in one line of shell script than there is in ten thousand lines of C.”

The programmer, who was very proud of his mastery of C, said: “How can this be? C is the language in which the very kernel of Unix is implemented!”

Master Foo replied: “That is so. Nevertheless, there is more Unix-nature in one line of shell script than there is in ten thousand lines of C.”

The programmer grew distressed. “But through the C language we experience the enlightenment of the Patriarch Ritchie! We become as one with the operating system and the machine, reaping matchless performance!”

Master Foo replied: “All that you say is true. But there is still more Unix-nature in one line of shell script than there is in ten thousand lines of C.”

The programmer scoffed at Master Foo and rose to depart. But Master Foo nodded to his student Nubi, who wrote a line of shell script on a nearby whiteboard, and said: “Master programmer, consider this pipeline. Implemented in pure C, would it not span ten thousand lines?”

The programmer muttered through his beard, contemplating what Nubi had written. Finally he agreed that it was so.

“And how many hours would you require to implement and debug that C program?” asked Nubi.

“Many,” admitted the visiting programmer. “But only a fool would spend the time to do that when so many more worthy tasks await him.”

“And who better understands the Unix-nature?” Master Foo asked. “Is it he who writes the ten thousand lines, or he who, perceiving the emptiness of the task, gains merit by not coding?”

Upon hearing this, the programmer was enlightened.

asgard
()

давызаипали меня на лорквотез постить =)

Muromec ☆☆
()
Ответ на: комментарий от tailgunner

>Но цифры, полученные тобой, выглядят подозрительно, поэтому я сказал про strace (если тебе интересно выяснить причину медленной работы bash, конечно).

спасибо, с builtin'ами протупил. и с read тоже - он пробелы спереди удаляет. потому:

andrey@silverblood (~/Programs/test)$ cat test_c.c 
#include <stdio.h>

char line[1000];
char *p;

int main()
{
 FILE *fp = fopen("test_file", "r");
 while(!feof(fp))
 {
  fgets(line, sizeof(line), fp);
  for(p = line; (*p == ' ') && *p; p++);
  printf("%s", p);
 }
 fclose(fp);
}
andrey@silverblood (~/Programs/test)$ 

теперь интересно другое:

bash strace состоит из:

_llseek(0, 0, [35022], SEEK_CUR)        = 0
read(0, <текст>, 128)                   = 128
_llseek(0, -110, [35040], SEEK_CUR)     = 0
write(1, <текст>, 8)                    = 8
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbf806d08) = -1 ENOTTY (Inappropriate ioctl for device)

strace сишной проги:

read(3, <текст>, 4096)                  = 4096
write(1, <текст>, 4096)                 = 4096


имхо, баш можно оптимизировать для более быстрой работы

generatorglukoff ★★
() автор топика
Ответ на: комментарий от m57

>> имхо, баш можно оптимизировать для более быстрой работы >может не стоит?

хз, у некоторых и на оптимизацию баша стоит

Muromec ☆☆
()

1 тест ацтой

2 разница при возрастании производительности этих "некоторых" утилит человеком заметна не будет. А вот разница в трудоёмкости написания - запросто.

bugmaker ★★★★☆
()
Ответ на: комментарий от bugmaker

>1 тест ацтой

почему?

>2 разница при возрастании производительности этих "некоторых" утилит человеком заметна не будет. А вот разница в трудоёмкости написания - запросто

гм, а что проще - написать утилиту изначально на си/перле/питоне/руби//итд или сначала на писать на баше, заорать "ой, ###! оно тормозит нереально!" и переписать все на вышеприведенных языках?

generatorglukoff ★★
() автор топика
Ответ на: комментарий от generatorglukoff

> почему?

потому что погрешность совершенно непотребна

> что проще

проще сначала подумать, достаточно ли будет быстродействия баша, и насколько страшные вещи произойдут если оно будет чуток помедленнее. Как пример, я когда-то делал довольно сложную обработку больших текстовых файлов. Было проще накарябать скрипт на баше, запустить в бэкграунде с низким приоритетом и дожидаться результата сутки-полторы, чем заморачиваться с сями. Т.е. длительность обработки изначально принималась в расчёт. Если по твоему варианту, тоже годится. Проще заоптимизировать отдельные куски, про которые ты достоверно знаеш что оне неприемлемо тормозят и дёргать некоторые операции из сишной проги, чем делать ваще всю задачу на сях. Благо прототип на скриптовом сваять и выявить узкие места - минутное дело.

bugmaker ★★★★☆
()
Ответ на: комментарий от generatorglukoff

>гм, а что проще - написать утилиту изначально на си/перле/питоне/руби//итд или сначала на писать на баше, заорать "ой, ###! оно тормозит нереально!"

на баше вообще-то принято писать тулзы, производительность которых некритична. Проблема-то в чем? Что скрипт, запускаемый раз в час выполняется 300 мс вместо 10мс? =)

geek ★★★
()

cat file работает очень быстро ;-)

Не понимаю сути извращений в 

while read -r line; do
    echo "$line"
done < test_file

birdie ★★★★★
()
Ответ на: комментарий от geek

> на баше вообще-то принято писать тулзы, производительность которых некритична. Проблема-то в чем? Что скрипт, запускаемый раз в час выполняется 300 мс вместо 10мс? =)

А из этого складывается общая неторопливость линукса. Сплошные скрипты плюс масса ненужных и притом даже неотрываемых вещей. Спасибо хоть из ядра можно вытряхнуть всё лишнее без непосредственного влезания в исходники.

anonymous
()
Ответ на: комментарий от anonymous

>А из этого складывается общая неторопливость линукса. Сплошные скрипты плюс масса ненужных и притом даже неотрываемых вещей.

чушь какая. В каком месте эта неторопливость?

geek ★★★
()
Ответ на: комментарий от anonymous

> А из этого складывается общая неторопливость линукса.

Общая неторопливость линукса складывается когда что-то хотят сделать через жопу, прикрываясь целями "так хотелось". Башу столько лет, что если б твоя (очень простая) проблема сильно кого-то волновала, её давно решили бы. И её решили, между прочим :)

m57
()
Ответ на: комментарий от anonymous

> А из этого складывается общая неторопливость линукса.

"А сейчас мы медленно спустимся и пере$бем все стадо" (старый бычара).

annoynimous ★★★★★
()
Ответ на: комментарий от wieker

К вопросу о синтетических тестах и перле с питоном )))

for i in `seq 1 100000`; do echo "AAAAAAAAA" >> test_file; done

[octy@octylt samba-docs]$ cat 1.py
#!/usr/bin/python
f = open ("test_file", "r")
lines = f.readlines()
for x in lines:
    print x

[octy@octylt samba-docs]$ cat 1.pl
open (A, "<test_file");
while (<A>) {
    print;
}

[octy@octylt samba-docs]$ time perl 1.pl > /dev/null

real    0m0.078s
user    0m0.060s
sys     0m0.010s

[octy@octylt samba-docs]$ time python 1.py > /dev/null

real    0m0.349s
user    0m0.340s
sys     0m0.010s

:D

octy ★★
()
Ответ на: комментарий от anonymous

> из этого складывается общая неторопливость линукса.

Какая неторопливость? Из startup-time скриптов она склавдывается? Смешно.

tailgunner ★★★★★
()

тестите:

/*
* compile:
* as -o test.o test.s
* ld -o test test.o
*/

.equ SYS_EXIT, 1
.equ SYS_READ, 3
.equ SYS_WRITE, 4
.equ SYS_OPEN, 5
.equ SYS_CLOSE, 6

.equ BUFLEN, 0x1000

.globl _start
_start:
movl $SYS_OPEN, %eax
movl $fname, %ebx
xorl %ecx, %ecx
int $0x80

cmpl $0, %eax
jl exit

movl %eax, (fd)

movl $buf, %ecx
rw_loop:
movl $SYS_READ, %eax
movl (fd), %ebx
movl $BUFLEN, %edx
int $0x80

cmpl $0, %eax
jle close

mov %eax, %edx
movl $SYS_WRITE, %eax
xorl %ebx, %ebx
incl %ebx
int $0x80

cmpl %eax, %edx
jne close
jmp rw_loop

close:
movl $SYS_CLOSE, %eax
movl (fd), %ebx
int $0x80

exit:
movl $SYS_EXIT, %eax
xorl %ebx, %ebx
int $0x80

.data
fname:
.asciz "test_file"

.bss
.comm fd, 4
.comm buf, BUFLEN

anonymous
()

Эльфы снова побеждают нагов?

r_asian ★☆☆
()
Ответ на: комментарий от octy

>К вопросу о синтетических тестах и перле с питоном )))

К вопросу о владении Питоном:
from sys import stdout
for i in file("aa.py"): stdout.write(i)

vsemnazlo
()
Ответ на: комментарий от vsemnazlo

Согласен, я просто скопировал код wieker'a

однако ж с твоим кодом 

[octy@octylt samba-docs]$ time python 2.py > /dev/null

real    0m0.159s
user    0m0.130s
sys     0m0.020s

Так что всё равно )
No holy wars, тест-то синтетический )

octy ★★
()
Ответ на: комментарий от vsemnazlo

Угу )) perl - медленнее ))

[octy@octylt samba-docs]$ cat 2.pl
open (A, "<test_file");
@s = <A>;
for $i (@s) {print}

[octy@octylt samba-docs]$ time perl 1.pl > /dev/null

real    0m0.641s
user    0m0.320s
sys     0m0.210s

octy ★★
()

В начале любой толковой книги/руководства по bash/etc чётко написано о преимуществах и недостатках, в каких случаях его стоит использовать, а в каких - не стоит.

Ты ещё один человек, который выполнил никому не нужное сравнение, результат которого известен заранее, т.е - зря потратил своё время.

frame ★★★
()

А это ничего, что bash это во-первых интерпретатор, а во-вторых, строчка echo "$line" парсится для каждой строчки файла данных?

no-dashi ★★★★★
()
Ответ на: комментарий от no-dashi

>А это ничего, что bash это во-первых интерпретатор, а во-вторых, строчка echo "$line" парсится для каждой строчки файла данных?

strace bash'а указывает на полное использование builtin'ов, т.е. оно может работать не медленнее сишной проги

generatorglukoff ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.