воскресенье, 15 февраля 2009 г.

Сборка Firefox для Windows работает быстрее сборки для Linux

Недавно прочитал новость на opennet.ru о том что даже под Wine Firefox работает быстрее родного варианта. Решил проверить: всё таки у меня Firefox собран "своими руками" можно сказать, а под Windows сборка рассчитана на совместимость с i586.
В оригинале статьи использовались тесты SunSpider, V8 Benchmark 3 и Dromaeo. От использования V8 Benchmark 3 я отказался ввиду того, что раз от раза он выдаёт разные результаты, т.е. по хорошему если его использовать, то надо запускать его несколько раз и усреднять результаты, а я - человек ленивый....
Тестирование проводилось в условиях: одноядерный Athlon64 3000+, 1GB RAM, Gentoo x86_64 (kernel 2.6.28).
Ниже результаты тестов.
Dromaeo:
Тест Firefox/3.0.6 (Native) Firefox/3.0.6 (Wine)
Total Score: 22.15runs/s ±5.30% 28.24runs/s ±4.15%
▶ 3D Mesh Transformation 15.32runs/s ±11.28% 26.22runs/s ±40.89%
▶ 3D Raytrace 30.60runs/s ±22.65% 31.18runs/s ±13.33%
▶ AES Encryption/Decryption 14.01runs/s ±42.71% 13.12runs/s ±7.45%
▶ Arrays 57.80runs/s ±4.57% 64.22runs/s ±3.76%
▶ Base 64 Encoding and Decoding 22.07runs/s ±18.07% 21.11runs/s ±23.14%
▶ Bitwise And 55.75runs/s ±1.40% 45.64runs/s ±1.20%
▶ Code Evaluation 81.20runs/s ±33.84% 85.26runs/s ±30.02%
▶ Compute Bits in Byte 17.06runs/s ±1.16% 13.66runs/s ±1.24%
▶ Compute Bits in Byte (2) 21.84runs/s ±1.27% 15.80runs/s ±1.34%
▶ DNA Sequence Alignment 39.26runs/s ±17.93% 41.48runs/s ±9.06%
▶ DNA Sequence Counting 18.27runs/s ±2.63% 19.66runs/s ±2.35%
▶ DOM Attributes 28.12runs/s ±8.26% 37.57runs/s ±10.72%
▶ DOM Attributes (Prototype) 41.12runs/s ±8.19% 61.07runs/s ±5.24%
▶ DOM Attributes (jQuery) 36.02runs/s ±5.52% 46.58runs/s ±17.75%
▶ DOM Events (Prototype) 28.83runs/s ±32.56% 36.07runs/s ±14.34%
▶ DOM Events (jQuery) 21.43runs/s ±15.26% 26.56runs/s ±6.37%
▶ DOM Modification 10.11runs/s ±11.71% 46.05runs/s ±7.59%
▶ DOM Modification (Prototype) 11.08runs/s ±7.34% 15.06runs/s ±2.97%
▶ DOM Modification (jQuery) 19.58runs/s ±9.36% 37.27runs/s ±6.47%
▶ DOM Query 112.18runs/s ±1.07% 160.51runs/s ±2.25%
▶ DOM Style (Prototype) 30.43runs/s ±8.99% 43.00runs/s ±5.74%
▶ DOM Style (jQuery) 20.10runs/s ±20.31% 28.92runs/s ±9.31%
▶ DOM Traversal 6.32runs/s ±1.58% 9.30runs/s ±1.13%
▶ DOM Traversal (Prototype) 26.84runs/s ±8.38% 36.74runs/s ±6.26%
▶ DOM Traversal (jQuery) 12.17runs/s ±2.23% 16.79runs/s ±2.23%
▶ Date Formatting 54.91runs/s ±25.13% 72.39runs/s ±1.56%
▶ Date Formatting (2) 33.11runs/s ±39.51% 38.37runs/s ±34.54%
▶ DeltaBlue Constraint Solving 19.29runs/s ±1.40% 20.52runs/s ±1.34%
▶ Fannkuch 25.99runs/s ±0.94% 21.75runs/s ±1.13%
▶ MD5 Hashing 39.50runs/s ±30.34% 37.60runs/s ±1.03%
▶ N-Body Rotation and Gravity 12.98runs/s ±62.57% 19.06runs/s ±1.68%
▶ Partial Sum Calculation 23.55runs/s ±57.08% 47.93runs/s ±56.54%
▶ Prime Number Computation 12.77runs/s ±46.26% 12.40runs/s ±30.19%
▶ Prime Number Computation (2) 10.18runs/s ±32.18% 15.00runs/s ±4.04%
▶ RSA Encryption/Decryption 3.53runs/s ±16.88% 3.50runs/s ±0.98%
▶ RayTracer 0.94runs/s ±27.14% 1.55runs/s ±14.28%
▶ Recursive Number Calculation 49.20runs/s ±1.08% 38.64runs/s ±2.50%
▶ Regular Expressions 10.17runs/s ±1.32% 12.12runs/s ±1.41%
▶ Richards Benchmarks 36.57runs/s ±0.62% 34.82runs/s ±1.13%
▶ Rotating 3D Cube 32.17runs/s ±40.61% 30.39runs/s ±17.13%
▶ SHA1 Hashing 42.99runs/s ±2.53% 35.34runs/s ±2.07%
▶ Script Unpacking 5.13runs/s ±11.92% 5.48runs/s ±4.49%
▶ Spectral Norm of a Matrix 5.85runs/s ±180.44% 28.99runs/s ±2.84%
▶ String Parsing and Searching 1.41runs/s ±34.47% 2.41runs/s ±25.62%
▶ Strings 67.45runs/s ±6.29% 62.34runs/s ±3.89%
▶ Tag Cloud Creation 23.29runs/s ±13.53% 31.59runs/s ±18.38%
▶ Traversing Binary Trees 22.11runs/s ±1.84% 28.03runs/s ±15.72%
▶ Trigonometric Calculation 45.32runs/s ±1.37% 31.77runs/s ±1.69%
▶ Validate User Input 26.56runs/s ±34.56% 27.43runs/s ±44.77%
Total Score: 22.15runs/s ±5.30% 28.24runs/s ±4.15%

Первый тест подтвердил результаты из оригинальной статьи.
Идём дальше...
SunSpider:
Тест Сравнение Firefox/3.0.6 (Wine) Firefox/3.0.6 (Native)
ИТОГ 1.14x as fast 11327.2ms +/- 2.3% 9914.6ms +/- 1.4%
3d 1.23x as fast 1456.8ms +/- 16.7% 1182.4ms +/- 3.7%
access 1.25x as fast 1954.8ms +/- 2.3% 1569.6ms +/- 2.1%
bitops 1.32x as fast 1725.6ms +/- 2.4% 1304.8ms +/- 2.5%
controlflow 1.26x as fast 157.2ms +/- 0.7% 124.4ms +/- 0.9%
crypto 1.21x as fast 730.4ms +/- 2.7% 605.6ms +/- 3.7%
date 1.16x as slow 769.6ms +/- 5.6% 889.2ms +/- 6.4%
math 1.27x as fast 1352.8ms +/- 1.6% 1069.0ms +/- 3.7%
regexp 1.09x as slow 722.4ms +/- 3.9% 789.6ms +/- 9.5%
string - 2457.6ms +/- 12.1% 2380.0ms +/- 2.8%

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

пятница, 13 февраля 2009 г.

KDE 4.2 и Qt 4.5.0 RC1

Вчера обнаружил в портежах обновление Qt. Обновился он до Qt 4.5.0 RC1. Надавно как раз прочитал, что KDE 4.2 с ним работает быстрее и стабильнее (упоминание об этом в последнем обзаце). Решил проверить. И о чудо - действительно работает быстрее. Конечно это всё по ощущениям, но кажется что время отклика действительно уменьшилось. А вот насчёт стабильности пока ничего не могу сказать - надо поработать, а там будет видно.

четверг, 5 февраля 2009 г.

Отсеивание повреждённых фотографий

Данный пост является продолжением поста "Восстановление и каталогизация фотографий"

Казалось бы восстановление утраченных фотографий окончено, но при беглом осмотре обнаружились повреждённые фотографии, которые бы неплохо отсеить. Фотографий много, поэтому вручную каждую просматривать не вариант. В поиках вариантов обратил внимание на модуль для работы с изображениями PIL. Путём экспериметов обнаружилась закономерность: на всех проверенных повреждённых фотографиях функция histogram выбрасывала исключение. Эта особенность и была положена в основу приведённого ниже скрипта. Он (скрипт) принимает два аргумента: исходную директорию и результирующую директорию. Скрипт проходит исходную директорию, включая поддиректории, и переносит повреждённые изображения в результирующую директорию. Так же переносимые файлы переименовываются по следующиему шаблону: [имя_директории]_[имя_фала]. В ситуации с вложенностью, описанной в предыдущей статье, это обеспечивает несовпадение имён.

Вот собственно текст скрипта:
#!/usr/bin/env python
import os
import sys
import Image
import shutil

def check_file(file, output_dir):
    print 'Processing file ' + file + ': ',
    im = Image.open(file)
    try:
        im.histogram()
        print 'Fine'
    except IOError:
        print 'Broken. Moving...'
        dir, file_name = os.path.split(file)
        file_name = os.path.split(dir)[1] + '_' + file_name
        shutil.move(file, os.path.join(output_dir, file_name))
    except KeyboardInterrupt:
        print 'Exiting...'
        sys.exit(1)
    except:
        print 'Unexpexted exception'

for root, dirs, files in os.walk(sys.argv[1]):
    [check_file(os.path.join(root, f), sys.argv[2]) for f in files if f.endswith('.jpg')]

среда, 4 февраля 2009 г.

Восстановление и каталогизация фотографий

Недавно обнаружил отсутствие наличия папки с фотографиями на жёстком диске. Обидно - 20ГиБ отсортированных фотографий. Восстановить данные впринципе не проблема - foremost нам в помощь:

foremost -i /dev/sda6 -dvqT -t jpg -o /mnt/gentoo/found
Эта команда сканирует /dev/sda6 на предмет наличия JPEG-файлов и складирует их в директорие /mnt/gentoo/found/.

Данные получили. Но вот что делать со структурой папок? Ведь восстанавливаюсь только данные. Имена, пути - всё это теряется.
Чтобы как-то рассортировать фотографии по папкам был написан скрипт, который берёт дату и время из EXIF каждого файла и перемащает его исходя из шаблона:
output_dir/[date]/[time].[ext]

Вот текст скрипта:

#!/usr/bin/env python
import sys
import os
import shutil

from mmpython import *

def organize(input_dir, output_dir):
    "Move files from input directory to output directory in form 'output_dir/<date>/<time>.jpg'"
    
    # all files without dates will be stored in 'output_dir/others/<files_without_date>.jpg'
    files_without_date = 0

    files = os.listdir(input_dir)

    for file_name in files:
        print u'Processing file ' + file_name

        info = parse(os.path.join(input_dir,file_name))

        if not isinstance(info, mediainfo.ImageInfo):
            print 'File type expected to be image.'
            continue

        if not hasattr(info, 'date') or not info.date or len(info.date.split(' ')) != 2:
            (dir, file) = ('others', unicode(files_without_date))
            files_without_date += 1
        else:
            (dir, file) = info.date.replace(':', '-').split(' ')

        newdir = os.path.join(output_dir, dir)
        if not os.path.exists(newdir):
            os.makedirs(newdir, mode=0777)
        elif not os.path.isdir(newdir):
            print "Failedto create directory: entry with the same name exists."
            continue

        new_file_path = os.path.join(newdir, file)
        tmp_file_path = new_file_path
        j = 0
        
        ext = os.path.splitext(file_name)[1]
        while os.path.exists(tmp_file_path + ext):
            tmp_file_path = new_file_path + '_'  +unicode(j)
            j += 1
        new_file_path = tmp_file_path

        shutil.move(os.path.join(input_dir, file_name), new_file_path + ext)
        print "File successfully moved to "+ new_file_path + ext

if __name__ == "__main__":
    organize(sys.argv[1], sys.argv[2])

Запускаем:
./cataloger.py /путь/к/исходному/каталогу/ /куда/ложить/результат/

Feature request

Только что запостил свой первый bug, точнее feature request в bugs.kde.org. Постепенно превращаюсь в нормального пользователя свободного ПО :) Теперь ещё исходники поправить самому и патч им отправить, что собственно они и рекомендуют.

Мой первый пост

Вот мой первый пост. Пост ни о чём. Так просто, проверить как это всё работает. Вроде как "Hello, World!".