LINUX.ORG.RU

md5 (каждую строку в файле)


2

1

Имеется текстовый файл с 2 ГБ данных. Нужно каждую строку похэшить в md5 и сохранить в файл, вот что получилось.

#!/bin/bash
while read line; do echo -n $line|md5sum|awk '{print $1}'|tr '[a-z]' '[A-Z]' >> md5.txt; done < text.txt
Проблема в том что все это делается очень долго, есть у кого мысли как ускорить процесс?


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

print тока в 3м питоне функция,а у меня второй

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

А старый зверь где?

все живы, всё хорошо :) А вот лысая кошка была не наша, я просто чью-то фотку повесил по случаю приближения 1 апреля :)

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

файл взял не такой большой - 15Гб, чтоб не ждать долго, но перед каждым запуском очищал дисковый кеш через echo 3 > /proc/sys/vm/drop_caches, вот результаты:

tcc - 4m28.818s
perl - 4m28.948s
python - 5m49.792s

tcc и perl явно уперлись в IO, в отличие от питона, но он отстал в принципе ненамного, итого, как по мне, perl для данной задачи всех зарулил

wota ★★
()
Последнее исправление: wota (всего исправлений: 1)
Ответ на: комментарий от MKuznetsov

ещё можно увеличить буфер для out setvbuf(out,malloc(32*1024*1024),...)
и избавиться от множества fputc

без разницы, даже наоборот - у меня fputc чуть быстрее fputs оказался, но это все в пределах погрешности

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

без разницы, даже наоборот - у меня fputc чуть быстрее fputs оказался, но это все в пределах погрешности

странно.. в вашем исходнике ради эксперимента заменил 17 fputc`ов на 1 fwrite, стало процентов на 40% шустрее (то есть больше погрешности).

    static char hextab[256][3];
    for(i=0;i<256;i++)
       sprintf(hextab[i],"%02X",i);
    static unsigned char mdtext[34];
    mdtext[32]='\n';
    mdtext[33]=0;
    while( ( read = getline( &line, &len, in ) ) != -1 ) {
        MD5( line, read, md );
        for( i = 0 ; i < 16 ; ++i )
    	  	*(unsigned short *)(mdtext+i*2)=*(unsigned short *)(hextab+md[i]); // два байта переслать :)
        fwrite(mdtext,33,1,out);
    }

а вот увеличение буфера out действительно выигрыша не даёт.

ps. все варианты с tcc и большими файлами стабильно крешаться на выходе. Пришлось ещё exit(0) добавлять. Без него :

*** glibc detected *** /usr/bin/tcc: double free or corruption (out): 0x0000000000ced3b0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7ae56)[0x7f846ef2ee56]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x6c)[0x7f846ef3313c]
/usr/bin/tcc[0x402c3d]
/usr/bin/tcc[0x41749c]
/usr/bin/tcc[0x401865]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7f846eed530d]
/usr/bin/tcc[0x401a4d]
======= Memory map: ========
00400000-00424000 r-xp 00000000 08:11 9749144                            /usr/bin/tcc
00623000-00624000 r--p 00023000 08:11 9749144                            /usr/bin/tcc
00624000-00625000 rw-p 00024000 08:11 9749144                            /usr/bin/tcc
00625000-00639000 rw-p 00000000 00:00 0 
00cd4000-00d0c000 rw-p 00000000 00:00 0                                  [heap]
00d0c000-00d0d000 rwxp 00000000 00:00 0                                  [heap]
00d0d000-00d54000 rw-p 00000000 00:00 0                                  [heap]
7f8468000000-7f8468021000 rw-p 00000000 00:00 0 
7f8468021000-7f846c000000 ---p 00000000 00:00 0 
7f846e6d7000-7f846e6ec000 r-xp 00000000 08:11 11144894                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f846e6ec000-7f846e8eb000 ---p 00015000 08:11 11144894                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f846e8eb000-7f846e8ec000 r--p 00014000 08:11 11144894                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f846e8ec000-7f846e8ed000 rw-p 00015000 08:11 11144894                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f846e8ed000-7f846e904000 r-xp 00000000 08:11 11144956                   /lib/x86_64-linux-gnu/libz.so.1.2.3.4
7f846e904000-7f846eb03000 ---p 00017000 08:11 11144956                   /lib/x86_64-linux-gnu/libz.so.1.2.3.4
7f846eb03000-7f846eb04000 r--p 00016000 08:11 11144956                   /lib/x86_64-linux-gnu/libz.so.1.2.3.4
7f846eb04000-7f846eb05000 rw-p 00017000 08:11 11144956                   /lib/x86_64-linux-gnu/libz.so.1.2.3.4
7f846eb05000-7f846ec8d000 r-xp 00000000 08:11 11141228                   /lib/x86_64-linux-gnu/libcrypto.so.1.0.0

tcc 0.9.25

тот-же код, но скомпилённый gcc работает нормально. Где-то что-то с памятью, но valgrind натравливать лень :)

так что поосторожнее там с tcc

MKuznetsov ★★★★★
()

Взял за образец текст отсюда.

$ ls -alnh found5.txt_Ascii.txt 
-rw-rw-r-- 1 500 500 822K апр.   3 20:36 found5.txt_Ascii.txt
Потом для увеличения размера файла — несколько манипуляций
$ mv found5.txt_Ascii.txt f5.txt
$ cp f5.txt 12.txt
$ enconv 12.txt
$ cat 12.txt >> f5.txt
$ wc -l f5.txt 
11630 f5.txt
$ ls -alnh f5.txt 
-rw-rw-r-- 1 500 500 2,3M апр.   3 20:40 f5.txt

Твой скрипт под именем «1.sh». Мой «lor3.py».

$ time ./1.sh f5.txt

real	0m25.476s
user	0m7.708s
sys	0m26.938s

$ time ./lor3.py f5.txt

real	0m0.088s
user	0m0.053s
sys	0m0.010s

Текст самого скрипта

$ cat lor3.py 
#!/bin/python
import sys, hashlib

if len(sys.argv) > 1:
    fn1 = sys.argv[1]
    fn2 = "md5p1.txt"
    f2 = open(fn2, "w")
    b = [(hashlib.md5(x.strip()).hexdigest().upper() + "\n") for x in open(fn1, "r").readlines()]

    try:
        f2.writelines(b)
    except:
        pass

    f2.close()


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

Проведите в Ангарск нормальный интернет, а то до него пока только первое сообщение дошло. Он же сейчас на остальные 60 отвечать станет.

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

А теперь подготавливаем данные «f6.txt».

$ for i in `seq 1000`; do cat f5.txt >> f6.txt; done;
$ ls -alnh f6.txt 
-rw-rw-r-- 1 500 500 2,2G апр.   3 20:44 f6.txt
И переходим к настоящим измерениям.
$ time ./lor3.py f6.txt

real	0m32.750s
user	0m28.362s
sys	0m2.383s

Итого. Результат «md5p1.txt» ( 2,2G --> 367M ) получился за 32 секунды.
$ ls -alhn md5p1.txt 
-rw-rw-r-- 1 500 500 367M апр.   3 20:46 md5p1.txt
«$ time ./1.sh f6.txt» считает до сих пор.

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

странно.. в вашем исходнике ради эксперимента заменил 17 fputc`ов на 1 fwrite, стало процентов на 40% шустрее (то есть больше погрешности).

40% - это как-то слишком много, особенно учитывая, что в том же цикле md5 считается

ps. все варианты с tcc и большими файлами стабильно крешаться на выходе

это из-за getline и старого tcc, у меня tcc из транка - там это профиксили

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

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

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