Вход | Регистрация

Компресия

  • Нека тук обсъждаме проекта за компресия

    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)