为什么我的Clojure项目在Raspberry Pi上变慢?

时间:2014-02-11 15:48:38

标签: audio clojure raspberry-pi

我一直在为我的Raspberry Pi编写一个简单的Clojure框架来播放音乐(以及其他一些东西)。程序解析给定音乐目录中的歌曲,然后通过TCP接口开始侦听控制命令(如开始,停止,下一首歌曲)。

代码可以通过GitHub获得: https://github.com/jvnn/raspi-framework

当前版本在我的笔记本电脑上工作得很好,它会在指示时开始播放音乐(使用JLayer库),更改歌曲,并按照应有的方式停止播放。 uberjar也需要几秒钟才能在笔记本电脑上启动,但是当我尝试在Raspberry Pi上运行时,事情变得非常缓慢。

启动程序以便加载所有类并且实际程序代码开始执行需要一分钟。我尝试使用-verbose:class开关来运行它,似乎jvm花费了整个时间来加载大量的类(对于Clojure和其他所有东西)。

当程序最终启动时,它会对给定的命令做出反应,但回放非常迟缓。有一个短的亚秒声,然后暂停几乎一秒钟,然后另一个声音,另一个停顿等......所以程序试图播放一些东西,但它只是不能足够快。 CPU使用率接近98%。

现在,拥有一部Android手机,我确信Java可以很好地在这样的硬件上执行,可以播放一些没有任何麻烦的mp3文件。我知道JLayer(或其中的一部分)用于gdx游戏开发框架(也可以在Android上运行),所以它也不应该是一个问题。

所以一切都指向我是问题所在。我可以用leiningen做什么(aot已经为所有文件启用了),Raspberry Pi,或者我的代码可以让事情变得更快?

谢谢你的时间!

更新 我做了一个小小的测试用例以排除一些可能性,并且以下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毫秒的暂停。

1 个答案:

答案 0 :(得分:4)

对我来说最明显的是你有很多未暗示的互操作代码,导致非常昂贵的运行时反射。尝试运行lein check(我认为它是内置的,但也许你需要一个插件)并修复它指出的反射问题。