На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Коротко о разделе:
Здесь разрешается создавать темы, относящиеся к любому языку программирования, для которого не существует раздела на форуме (например, Lisp, Tcl/Tk, FORTRAN и т.д.). Если раздел для нужного Вам языка есть, большая просьба создавать тему в нем.
Вопросы, связанные с JScript, Perl, PHP обсуждаются в разделе WWW Masters.

Обратите внимание:
1. Прежде чем задать вопрос, воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали.
2. Если Ваш вопрос связан с конкретным языком программирования, обязательно укажите название языка в имени темы.
3. Постарайтесь давать темам информативные названия. Темы с названиями типа "Помогите, горю" будут удалены.
4. Помните, чем грамотней будет задан Ваш вопрос, тем больше будет у Вас шансов получить на него ответ. Как правильно задавать вопросы
5. Ипользуйте тег [ code ] ...текст программы... [ /code ] для выделения текста программы.

Просьбы выполнить какую-либо работу за автора в этом разделе не обсуждаются. Темы с подобными просьбами будут перемещены или удалены. Для заказов у нас существуют специальные разделы: Разовые заказы и подработка, ПОМОЩЬ СТУДЕНТАМ.

Если кто не понял (а такие есть) — чтобы за вас решали ваши задачки, идите на другие ресурсы.

Полезные ссылки:
Есть. ;)
Наши Исходники | GPSS (en), GPSS (ru) (!) | Common Lisp | Tcl/Tk | Haskell | Lua
Модераторы: B.V.
  
> [Haskell] Оптимизация и профилирование
    Добрый день!

    Недавно начал пытаться использовать хаскелль в реальных задачах (конкретно - обработка звуковых сигналов), и застрял на производительности.
    Есть код, читающий сигнал из wav-файла:

    Wave.hs - содержит структуру данных Wave c "сырыми" данными, т.е. заголовком wav-файла и байтовой строкой с сигналом, + функционал по считыванию wav-файла в эту структуру.
    http://pastebin.com/wm53vVRx

    SignalSource.hs - содержит "чистовую" структуру данных, содерюащую сигнал и метаданные (пока только частоту), + функционал по преобразованию "сырых" данных в эту структуру.
    http://pastebin.com/Y7haSJX9

    Signal.hs - собственно сигнал, по факту - список из Integer'ов с определенными арифметическими операциями. Для удобства в модуле Aux.List арифметические операции определены и для списков.
    http://pastebin.com/74V4qjGW

    Теперь, если попытаться прочитать wav-файл (размер ~225k) и посчитать длину сигнала (количество отсчетов):
    ExpandedWrap disabled
      main = signalFromWave <$> readWaveFromFile sourceFile >>= print . sigLength . signal


    Оказвыается, что эта операция занимает аж 12 секунд. Собрал с ключиком -rtsopts и посмотрел вывод программы с ключами +RTS -sstderr. Вышло следующее:
    ExpandedWrap disabled
         9,071,278,288 bytes allocated in the heap
         4,687,384,520 bytes copied during GC
             2,555,736 bytes maximum residency (959 sample(s))
               169,472 bytes maximum slop
                     8 MB total memory in use (0 MB lost due to fragmentation)
       
                                          Tot time (elapsed)  Avg pause  Max pause
        Gen  0     10217 colls,     0 par    5.31s    5.32s     0.0005s    0.0017s
        Gen  1       959 colls,     0 par    3.63s    3.63s     0.0038s    0.0053s
       
        INIT    time    0.00s  (  0.00s elapsed)
        MUT     time    3.08s  (  3.08s elapsed)
        GC      time    8.94s  (  8.94s elapsed)
        EXIT    time    0.00s  (  0.00s elapsed)
        Total   time   12.02s  ( 12.03s elapsed)
       
        %GC     time      74.3%  (74.4% elapsed)
       
        Alloc rate    2,945,797,548 bytes per MUT second
       
        Productivity  25.7% of total user, 25.7% of total elapsed


    Т.е. программа вертится в пределах 8 мегабайт оперативы, но при этом так неистово аллоцирует память и чистит ее, что набегает аж 8.5 гигов за все время исполнения (просто чтение 225k данных и один проход по ним!). Как я понимаю, все дело в том, что при преобразовании ByteString в [Integer] у меня рекурсивно "откусывается" один Integer и заносится в список, после чего операция повторяетя с укороченной ByteString и увеличенным сигналом, т.е. в этот момент происходит перевыделение памяти под все данные, и память выделяется вместо одного раза по 225k аж {число отсчетов} x 225k.

    Тем не менее, я не могу понять, как это оптимизировать. В императивном языке я бы просто выделил массив байт заранее известного размера и считал бы все в него. Что можно сделать тут?

    P.S. Любые общие пожелания и комментарии по коду и стилю приветствуются. Wave читаю вручную специально (не прибегая к сторонним либам), чтобы поиграться с языком.
    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
    0 пользователей:


    Рейтинг@Mail.ru
    [ Script execution time: 0,0227 ]   [ 15 queries used ]   [ Generated: 28.03.24, 22:55 GMT ]