Нека тук обсъждаме проекта за компресия
Компресия
-
28.06.2010
-
@Светлин , аз не говоря за preprocessing ами за reducing по някакъв начин.Виж вътри ми се една идея в главата още не съм я написал немога да твърдя ,че е приложима.Има два варианта Компресия+(намаляне на битовете или моята идея да проработи и да даде резултат).В момента пиша други неща ,незнам дали ти си реализирал алгоритъма на Пайтън защото аз го направих и имам/х проблем с бързодействието ,който сега решавам и чак след това ще реализирам идеята си чак след като всичко работи и остана пред избора "моята идея" или намаляващ код.
28.06.2010 -
Още пиша задачата и тествам.
Проблемът с бързодействието при мен се оказа, че е най-вече заради четене и записване на по 1 байт, а също така и евентулно chr() и len(). Лесно се вижда, ползвай cProfile. Пример:
import cProfile def compress(file_in, file_out): .... cProfile.run("compress('myfile', 'myfile.lzw')")
29.06.2010 -
Имам същия проблем , след като направих cProfile и аз видях ,че len и chr и понякога ord ми заемат необичайно много време , но ще видим :)
29.06.2010 -
Да. Затова: дим да ги няма! Всичко с байтове: bytes и bytesarray. Първото е mutable. т.е.
b = bytes([1, 2, 3]) b += f.readbyte(1) # или ползваш някакъв array
29.06.2010 -
Ето и един съвет от мен. Ако ползвате функции в циклите, където обхождате входния файл, ги присвоете към локални променливи и ги извиквайте чрез тях. Особено, ако в имената им има точки. Например:
import struct ... for i in f.read(): b = struct.pack('B', i) ... l = len(b) ... outfile.write(b) ...
го направете така:
import struct ... pack = struct.pack ln = len write = output.write for i in f.read(): b = pack('B', i) ... l = ln(b) ... write(b) ...
По-късно може да постна и други дребни хитринки за ускоряване.
За колко време приблизително комресирате 50 мб файл?
29.06.2010 -
Освен това, видях, че се чудите дали да добавяте Huffman coding към LZW. Поне според мен, не си струва, тъй като ще забави допълнително алгоритъма. По-добре да се направи с phased-in bits, т.е. кодовете започват от някаква дължина и нарастват с 1, всеки път когато големината на речника премине граница 2 ** n, което реално не натоварва допълнително нещата. Плюс това, LZW + arithmetic encoding дава само 1-3% допълнителна компресия спрямо LZW + phased-in bits, а както знаем (или не знаем) arithmetic coding се спрява поне толкова добре колкото Huffman coding. :)
29.06.2010 -
Деляне, добре казано: сходни размисли пише и в книгите по въпроса. А засега само размишлявахме с колегата Руслан. За перформънса трябва още малко да го понацъкам, за да кажа реално как върви.
29.06.2010 -
Положението е доста зле.
file.read()
иfile.write()
заемат основната част от времето. Каквото и кеширане да измислям не става много по-бързо. Дефакто скоростта е 3 S/MB, което значи, че 700MB ще е ~35min. Това при условие, че се ползва едното ядро на 4200+. Доста зле ми изглежда.Компресията е от рода на 35%. Ползвам 64K речник и записвам цели двубайтови кодове. Поне е лесно, ако не друго.
Просто вече се чудя какво да измислям, но пък поне още мога да мисля. :-D
30.06.2010 (променeно 30.06.2010) -
Ами аз успях да смъкна компресиране на 800 мб файл до 20 минути. Наистина
read
е доста бавен, особено ако четеш по един байт. Това, което на мен ми помогна е следното:... buffer = f.read(1024*1024) for i in buffer: b = int_to_byte[i] ...
По този начин можеш да се обходи много бързо файла, но за съжаление
i` е от тип `int
. Затова предварително създадох речник от 256 елемента, който ми map-ва на всяко число съответстащия байт. И сега работата с байтове е доста по-лека от това да се правят разни списъци и прочие.30.06.2010 (променeно 30.06.2010) -
Браво за достигнатата скорост и благодаря за идеята. Принципно LZW е по-различен (и по-прост) от LZ77 и ще видя как да го приложа. Пробвах нещо подобно, но пак доста бавеше. Много шантава работа.
Постигна ли заветните 29.999999%? :-|
30.06.2010 -
Ами ако използвам достатъчно голям речник (разбирай 65536*8 и нагоре) стигнах 28.7% на големия файл. Иначе на други файлчета от по 50 мб дето тествам ми е падало и до 12%. Но не ми е чист LZW алгоритъма, тъй като съм добавял 1-2 оптимизациики.
30.06.2010 -
Забравих, да кажа, че има и друг начин за итерацията. Не знам дали е по-ефикасен. Според мен е същото.
for i in range(len(buffer)) buffer[b:b+1]
30.06.2010 -
И този съм го пробвал (какво ли не съм), но методът с речника е просто най-бърз от всичко.
30.06.2010 -
Сигурно в имплементацията ти все пак се наложи пакване на битове?
30.06.2010 -
Деляне, благоооодаря за идеята!
Сега бачка бързо и компресира повече, само че е за сметка на RAM-а.
30.06.2010 -
Някой пробва ли се с марковски модел поне от втори ред и малко трансформации, move to front + bwt + аритметично кодиране?
09.07.2010 (променeно 09.07.2010) -
Оттеглям въпроса си.
12.07.2010 (променeно 12.07.2010)