Forums > MaxMSP

Java, JavaScript or C

March 19, 2013 | 4:47 pm

Hey,
which language would u suggest for programming externals for max/msp?
i’m using Java for the moment but there seem to be serious CPU problems with Java externals within max.
i’d especially like to programme my own externals for using the kinect.

thanx
P


March 19, 2013 | 5:38 pm

C!!!
- no, seriously, JavaScript is easier… but if you can write some Java then you’ll have no problem with learning C, the Max API is somewhat trickier but if you have performance problems you’ll see the difference!

my 2 cents…
aa


March 19, 2013 | 5:43 pm

okidoko…thanx a lot…that’s what i heard, too. C is the solution, C it will be ;-)



Lee
March 19, 2013 | 6:45 pm

it really depends on what you want to do, if you need raw cpu power then C or Java, the call into Java is more expensive that a call into C, but the externals don’t have to be compiled for mac and windows as they run in the JVM… then again, Javascript can directly script gui elements without having to break into MAX, but won’t run as fast as C/Java (tho over time the js interpreters get smarter and faster….)


March 19, 2013 | 7:00 pm

Hmm, i have a friend who had very, very big CPU problems with a JAVA external he programmed and used in his patcher.
he had crackles in the sound and the patcher crashed regularly – he removed the JAVA stuff and everything works fine.
so he really recommends C….



Lee
March 20, 2013 | 2:06 am

I use java externals regularly and have no issues, but I don’t do anything audio intensive… Did he try sending his patch to c74 to see if they could identify any issues?


March 20, 2013 | 10:49 am

Java is pretty fast if you aren’t passing too much stuff over the Java/native boundary (i.e. between Java and Max). If you’re happy having a JVM installed then you can also use Python, Clojure or Ruby.

Javascript doesn’t run in the scheduler, making it (IMHO) only really usable for UI, interaction and housekeeping. If you’re happy with that, then you can also look into ClojureScript (which compiles into optimised Javascript), or CoffeeScript.


March 20, 2013 | 11:18 am

Your posts seem a bit like when you already had the answer in your mind and just needed some confirmation ;-)

Seriously, it really depends on what you’re doing. The obvious answer is C; however, there are scenarios when, actually, C wouldn’t be the fastest solution IMHO. For example, if you need to achieve something that has a highly optimized third-party solution in Java AND you don’t need to pass too frequently data between Max and MXJ, then you might end up with a more CPU-efficient (hence, faster) solution by using an optimized library in Java compared to the case when you try to build the stuff in C on your own. Development time and maintenance might also affect your decision, since a simple Javascript code for a simple task is much easier to maintain than the code of an external in Java (which IMHO is still easier to maintain than the code of an external in C, but that’s perhaps depending on your coding style and/or development tools as well). This last point is something that you won’t really consider when you create the external, but you’ll just hate yourself when you have to touch the code in, let’s say, two years from now, and you won’t even remember where to start with it…

HTH,
Ádám


March 20, 2013 | 11:27 am

BTW, my personal experience with Java in Max is that, unless you do some very specific task, there are no serious differences in CPU consumption compared to externals that achieve the same task in C (note that I mentioned ‘achieving the same task’ and not ‘using the same coding solutions’). If there are, that’s usually the symptom of bad design rather than an overall problem with Java. Indeed, to make something efficient, you need to optimize it, and by this I mean, as a first step, that when you design your external you should avoid things that would slow it down unnecessarily. In other words, if the task can be achieved in more than one way (which is usually the situation in complex situations when it is worth to build an external instead of using built-in objects), you should always choose the solution that best suits the actual language and environment.


March 22, 2013 | 12:32 pm

I didn’t know that — so if I’m sending MIDI data around (in overdrive mode, say) and one of the objects is a js object that processes that MIDI data, that’s going to have a significant impact on real-time performance (other than the actual CPU cycles to process javascript functions)?

—Javascript doesn’t run in the scheduler


March 22, 2013 | 1:45 pm

Correct.



Lee
March 22, 2013 | 5:04 pm

Hi Nick, I use js object to talk to live.remote~ objects with no (apparent) issue. seems that this is something i need to be thinking about from your post?


March 22, 2013 | 5:08 pm

So how are things scheduled in this case? Does the entire event sequence get moved off of the high priority thread at the point when a js object is encountered?

It sounds like I may need to replace a few of my javascript objects with C externals


March 22, 2013 | 5:32 pm

Correct – calls entering js/jsui get deferred to low priority.

For better timing accuracy you could look at something Java-based, although then you have the overhead of spinning up a JVM and sending stuff across the JNI boundary. I’ve sequenced with JVM-hosted languages without serious problems.



Lee
March 22, 2013 | 6:03 pm

I’ve never had problems running in js or java either – I guess overall if it isn’t affecting the high priority stuff that is going on then the only cost is extra cpu cycles of crossing the boundaries – this may become more apparent on lower spec machines, buy maybe as the js/java execution environments get better over time this becomes less of an issue… from conversations i’ve had with c74 guys, the gap between the overall performance of js and java is getting smaller over time….


March 22, 2013 | 7:46 pm

Apart from real-time stuff, this would explain some very anomalous behavior I’ve experienced for several years with my system, some of which I’ve reported on the forums, related to how does one know when a VST has finished loading.

It turns out that I am using a Javascript based dictionary for persistance and so I have a few objects that are used to load VSTs and configure their parameters. When I first built this and tried to play notes as soon as it seemed VSTs were loaded, I had many problems and so had to introduce several seconds of artificial delay.

If that javascript object is causing the entire loading process to be defered, such that regular event processing continues immediately, that would completely explain the problem.

It would also explain why it seemed to take longer to load a VST in my environment than if I just load one raw in a simple patcher.

This is VERY useful info.



Lee
March 23, 2013 | 3:05 am

I’d be very surprised if that was due to js… If we put this into perspective, whether we’re in the high priority thread or the lower priority thread, we’re still going to be running millions of ops per second… I’m not sure having to put a several second delay into your patch is due to running in js….


March 23, 2013 | 4:35 am

It’s not about speed or number of cycles/second.
Deferring the execution changes the order of execution. That can break stuff.

Consider for example the following patcher running in overdrive. The js object simply adds 1 to the incoming inlet and sends out the result. For the very first MIDI event, I would expect (and want) the output (in the max window) to be 3 but in fact I will get 1 because the js object is deferred and so the right inlet of the [+] is still 0

– Pasted Max Patch, click to expand. –

March 23, 2013 | 11:27 am

"The first thing to note is that at the time of this writing the Javascript implementation is single threaded and will only execute at low priority. For timing sensitive events the js and jsui objects should not be used for this reason."

Quoted from this article

http://cycling74.com/2004/09/09/event-priority-in-max-scheduler-vs-queue/

Unfortunately such essential info is not mentioned in the standard documentation.


March 23, 2013 | 12:35 pm

well, actually you can set
immediate = 1
in your javascript code. this will allow your methods to run in the scheduler. not everything can be made immediate (no scripting, no UI iirc) but as long as it’s just plain computation you should have no problems.

hth
aa


March 23, 2013 | 12:40 pm

… ok, here it is

http://cycling74.com/docs/max5/vignettes/js/jsthreading.html


March 23, 2013 | 12:45 pm

… but in the Max6 doc is stated
Note: Immediate mode has been deprecated as of Max version 6.0.

… ok, forget about that! and then, frankly, C is soooo much better… ;)



Lee
March 23, 2013 | 1:03 pm

I would definitely go C or Java if possible, unfortunately I’m doing m4l stuff so need js to talk to the LOM…..



Lee
March 24, 2013 | 5:37 am

dhjdhjdhj, i see your point… you could always defer the input in this case – midi is control rate, not audio rate after all….


March 24, 2013 | 11:49 am

But I think if you defer the midi input, scheduling at control rate (1 ms) is not applied anymore which may result in unpredictable latency.


March 24, 2013 | 12:02 pm

Defering MIDI processing is not an option. MIDI event processing has to be done in real time otherwise the results will be very sloppy.

The solution (for me) will be to rewrite my javascript routines as C (or C++) externals.



Lee
March 24, 2013 | 1:32 pm

yup…

would like to know what issued caused c74 to drop the ability of running js in the high pri thread…..


March 24, 2013 | 1:42 pm

HI !

@Lee
It might be due to dynamic memory allocation , garbage collection that might introduce some memory leaks as JS might be clearing itself slower , but thats just a dirty guess



Lee
March 24, 2013 | 1:49 pm

yeah, i would think something along those lines, would be interesting to know exactly what tho….


March 24, 2013 | 2:46 pm

The Javascript engine doesn’t support multithreading. (It’s not an issue with garbage collection; there are many GC’d languages which multithread happily; in fact, it often helps to run the garbage collector in its own thread.)


March 24, 2013 | 2:48 pm

Have a look at Rhino (the JS engine for the JVM); this might run JS code at high priority.



Lee
March 25, 2013 | 3:42 am

which js engine is currently used? I read somewhere it was SpiderMonkey… are you saying that it is Rhino or just to take a look at Rhino?


March 25, 2013 | 9:47 pm

Rhino is the pure-Java Javascript engine in Java 6. It seems to support multithreading:

https://developer.mozilla.org/en-US/docs/Rhino/Scopes_and_Contexts

It might therefore work at high priority (as well as in the UI thread).


March 25, 2013 | 10:00 pm

I’ve been experimenting with the "immediate" stuff in Max 5.1.9 and it completely solves the issues for which I had used artificial delays and defers as hacks.
However, even though I’m not able to switch over to Max 6, I’ve made sure so far that all my patchers do work in 6. If I start using "immediate", I’ll break that migration path.
Is there something different I have to do to get the high priority behavior with Max 6 and Rhino? If so then I’ll just isolate my changes as much as possible.



Lee
March 26, 2013 | 1:48 am

Can someone from c74 pls shed some light on this and also why the behaviour was changed between 5 and 6 – seems like a bit of a backwards step…


March 26, 2013 | 12:49 pm

Rhino as engine in Max would be awesome. This would enable us to use the Max 4 Live API within Java too (same for all the other JS APIs in Max). This would allow some really cool coding.


March 26, 2013 | 2:59 pm

I doubt it. The native Javascript will have been extended specifically with C linkage for the LiveAPI (as for patcher access, Dict, Sketch, MGraphics and so on). Rhino would only have access to anything that the JVM has access to.



Lee
March 26, 2013 | 11:52 pm

Also, if calling js caused a crossing from max into java it would make it more expensive to call…


Viewing 38 posts - 1 through 38 (of 38 total)