为什么我的 Clojure 项目在 Raspberry Pi 上运行缓慢?

J.N*_*nen 5 audio clojure raspberry-pi

我一直在编写一个简单的 Clojure 框架,用于为我的 Raspberry Pi 播放音乐(以及后来的一些其他东西)。该程序解析给定音乐目录中的歌曲,然后开始通过 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))))
Run Code Online (Sandbox Code Playgroud)

项目.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)
Run Code Online (Sandbox Code Playgroud)

因此,没有 core.async 也没有线程。播放确实变得更流畅了一些,但仍然是大约 200 毫秒的音乐和 200 毫秒的暂停。

ama*_*loy 5

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