2014-02-11 2 views
4

Я писал простую основу Clojure для воспроизведения музыки (а затем и некоторых других вещей) для моей малины Pi. Программа анализирует данный музыкальный каталог для композиций, а затем начинает прослушивание команд управления (таких как запуск, остановка, следующая песня) через интерфейс TCP.Почему мой проект Clojure медленный на малине Pi?

код доступен через GitHub: https://github.com/jvnn/raspi-framework

Текущая версия прекрасно работает на моем ноутбуке, он начинает играть музыку (с помощью библиотеки JLayer), когда проинструктированы, изменяет песни, и останавливается, как должно , Убержар занимает несколько секунд, чтобы начать работу с ноутбуком, но когда я пытаюсь запустить его на малиновом Pi, все становится безумно медленным.

Просто запустите программу, чтобы все классы были загружены, а фактический программный код начинает выполняться более чем через минуту. Я попытался запустить его с помощью переключателя -verbose: class, и кажется, что jvm тратит все время, просто загружая тонны классов (для Clojure и всего остального).

Когда программа, наконец, начинается, она реагирует на приведенные команды, но воспроизведение очень лаги. Существует короткий субсекундный звук, затем пауза в течение почти секунды, затем другой звук, другая пауза и т. Д. Итак, программа пытается что-то сыграть, но просто не может сделать это достаточно быстро. Использование процессора где-то близко к 98%.

Теперь, имея телефон Android и все, я уверен, что Java может быть выполнен на таком оборудовании достаточно хорошо, чтобы воспроизводить некоторые mp3-файлы без каких-либо проблем. И я знаю, что JLayer (или его части) используется в платформе разработки игр gdx (которая также работает на Android), поэтому это тоже не должно быть проблемой.

Так что все указывает на то, что я являюсь проблемой. Есть ли что-то, что я могу сделать с leiningen (aot уже включен для всех файлов), Raspberry Pi или мой код, который может ускорить работу?

Спасибо за ваше время!

UPDATE: Я сделал крошечный тест, чтобы исключить некоторые возможности и проблемы все еще существуют со следующим кодом Clojure:

(ns test.core 
    (:import [javazoom.jl.player.advanced AdvancedPlayer]) 
    (:gen-class)) 

(defn -main 
    [] 
    (let [filename "/path/to/a/music/file.mp3" 
     fis (java.io.FileInputStream. filename) 
     bis (java.io.BufferedInputStream. fis) 
     player (AdvancedPlayer. bis)] 
    (doto player (.play) (.close)))) 

project.clj:

(defproject test "0.0.1-SNAPSHOT" 
    :description "FIXME: write description" 
    :dependencies [[org.clojure/clojure "1.5.1"] 
       [javazoom/jlayer "1.0.1"]] 
    :javac-options ["-target" "1.6" "-source" "1.6" "-Xlint:-options"] 
    :aot :all 
    :main test.core) 

Таким образом, нет core.async и нет потоков. Воспроизведение сделало немного более плавным, но это все равно около 200 мс музыки и пауза 200 мс.

+0

Я думаю, что это может быть связано с меньшим размером кеша на процессоре pi. Clojure велик, но идиоматический Clojure гораздо более требователен с точки зрения сбоя кеша, чем большинство других языков (в частности, из-за его интенсивного использования неизменяемых структур данных). – noisesmith

+0

Я думаю, что это не объяснит проблемы с воспроизведением (и не очень медленное время запуска, как я предполагаю). Поскольку (по крайней мере, если код работает так, как я имел в виду, что он работает) во время воспроизведения, который обрабатывается библиотекой java, весь код Clojure должен стоять на стоянке и ждать ввода асинхронного канала. –

+0

Эта парковка, вероятно, связана с переключением контекста. Переключение контекста разбивает ваш кеш, что дорого (особенно с медленной шиной).Когда у вас есть медиапоток, который поступает непосредственно из ОЗУ (или даже диска) в устройство вывода без изменений, то, что пропускает его, - это переключение контекста, и чем больше кеша требуется контекстному коммутатору, тем более экстремальные проблемы пропуска будет. – noisesmith

ответ

4

Наиболее очевидным для меня является то, что у вас есть много не намеченного кода взаимодействия, что приводит к очень дорогому отражению во время выполнения. Попробуйте запустить lein check (я думаю, что это встроено, но, возможно, вам нужен плагин) и исправление проблем с отражением, которые он указывает.

+0

Спасибо за ответ. лейн-проверка ничего мне не сказала, единственный выход - «Компиляция пространства имен ...». Но я думаю, что отражение не может быть причиной длительного времени запуска, даже если это замедляет работу программы во время выполнения? –

+0

re startup time ... Clojure просто большой, а малина pi маленькая. Если вы видите, что время загрузки загружает классы при запуске, это, вероятно, связано с тем, что для загрузки требуется много классов. Я предполагаю, что ваш файл jar довольно здоров, по сравнению с тем, что хочет увидеть pi. – amalloy

+0

Хорошо, это то, чего я боялся услышать. Я надеялся, что будет что-то (оптимизация, разные версии java и т. Д.), Которые можно было бы сделать, чтобы улучшить ситуацию. –

Смежные вопросы