简体   繁体   English

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

[英]Why is my Clojure project slow on Raspberry Pi?

I've been writing a simple Clojure framework for playing music (and later some other stuff) for my Raspberry Pi. 我一直在为我的Raspberry Pi编写一个简单的Clojure框架来播放音乐(以及其他一些东西)。 The program parses a given music directory for songs and then starts listening for control commands (such as start, stop, next song) via a TCP interface. 程序解析给定的音乐目录中的歌曲,然后通过TCP接口开始监听控制命令(例如开始,停止,下一首歌曲)。

The code is available via GitHub: https://github.com/jvnn/raspi-framework 该代码可通过GitHub获得: https//github.com/jvnn/raspi-framework

The current version works just fine on my laptop, it starts playing music (using the JLayer library) when instructed to, changes songs, and stops just as it should. 当前版本在我的笔记本电脑上运行得很好,它会在指示时开始播放音乐(使用JLayer库),更改歌曲并停止播放。 The uberjar takes a few seconds to start on the laptop as well, but when I try to run it on the Raspberry Pi, things get insanely slow. uberjar也需要几秒钟才能在笔记本电脑上启动,但是当我尝试在Raspberry Pi上运行时,事情变得非常缓慢。

Just starting up the program so that all classes are loaded and the actual program code starts executing takes way over a minute. 只需启动程序以便加载所有类并且实际程序代码开始执行需要一分钟。 I tried to run it with the -verbose:class switch, and it seems the jvm spends the whole time just loading tons of classes (for Clojure and everything else). 我尝试使用-verbose:class开关运行它,似乎jvm花费了整个时间只加载了大量的类(对于Clojure和其他所有东西)。

When the program finally starts, it does react to the commands given, but the playback is very laggy. 当程序最终启动时,它会对给定的命令做出反应,但回放非常迟缓。 There is a short sub-second sound, then a pause for almost a second, then another sound, another pause etc... So the program is trying to play something but it just can't do it fast enough. 有一个短的亚秒声,然后暂停几乎一秒钟,然后另一个声音,另一个停顿等......所以程序试图播放一些东西,但它只是不能足够快。 CPU usage is somewhere close to 98%. CPU使用率接近98%。

Now, having an Android phone and all, I'm sure Java can be executed on such hardware well enough to play some mp3 files without any troubles. 现在,拥有一部Android手机,我确信Java可以在这样的硬件上执行,足以播放一些没有任何麻烦的mp3文件。 And I know that JLayer (or parts of it) is used in the gdx game development framework (that also runs on Android) so it shouldn't be a problem either. 我知道JLayer(或其中的一部分)用于gdx游戏开发框架(也在Android上运行),所以它也不应该是一个问题。

So everything points in me being the problem. 所以一切都指向我是问题所在。 Is there something I can do either with leiningen (aot is already enabled for all files), the Raspberry Pi, or my code that could make things faster? 我可以用leiningen(aot已经为所有文件启用),Raspberry Pi或我的代码可以做得更快吗?

Thanks for your time! 谢谢你的时间!

UPDATE: I made a tiny test case to rule out some possibilities and the problems still exist with the following Clojure code: 更新:我做了一个小测试用例来排除一些可能性,并且以下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))))

The project.clj: 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)

So, no core.async and no threading. 所以,没有core.async和没有线程。 The playback did get a bit smoother, but it's still about 200ms music and 200ms pause. 播放确实有点平滑,但它仍然是大约200ms的音乐和200ms的暂停。

Most obvious to me is that you have a lot of un-hinted interop code, leading to very expensive runtime reflection. 对我来说最明显的是你有很多未暗示的互操作代码,导致非常昂贵的运行时反射。 Try running lein check (I think that's built in, but maybe you need a plugin) and fixing the reflection issues it points out. 尝试运行lein check (我认为它是内置的,但也许你需要一个插件)并修复它指出的反射问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM