6 ms·
I've been hacking Rails since 2004, and I've made the switch to Java (dropwizard+mustache) for basic web development this year (sometimes with a meteor-like mic
by fizx 14y ago
I've been hacking Rails since 2004, and I've made the switch to Java (dropwizard+mustache) for basic web development this year (sometimes with a meteor-like micro-framework I rolled myself).
Benefits:
- Higher quality code. Java is easier to refactor than Ruby, which makes up for the lower language power.
- Performance!
- Actual concurrency!
- Faster server spinup and incremental changes. Rails with 20 gems in development mode is super sluggish.
- Better library ecosystem!
- Better dependency management system (maven > rubygems)
- Better debuggers
- Better profilers
- Easier deployment and ops environment(java -jar myjar, vs bundle install, ruby/passenger/unicorns)
- Reasonable in-process metrics
- lucian1900 14y agoIs Rails that slow? There's absolutely nothing on my machine slower to start up that the jvm.
- sterwill 14y agoThe JVM is very fast to start on my machines. For Java 7 on Linux x86_64: t:~% time java HelloWorld Hello from Java! java HelloWorld 0.04s user 0.02s system 94% cpu 0.063 total It's not as fast as C or Ruby, but who cares about .063 seconds spent once at start-up? t:~% time ./hello Hello from C! ./hello 0.00s user 0.00s system 0% cpu 0.002 total t:~% time ruby hello.rb Hello from Ruby! ruby hello.rb 0.00s user 0.00s system 86% cpu 0.009 total
- democracy 14y agoHow about the same test with a '-client' switch...
- sterwill 14y agoI get the same times, more or less. I'm not sure the -client switch changes any behavior that early in the VM's life, before any garbage collection or sizable allocation happens. It would still be using a 64-bit data model with the -client switch (-d32 gives me: "Error: This Java instance does not support a 32-bit JVM.").
- astrange 14y ago"-client" has no effect in 64-bit.
- IsTom 14y agoI'm not sure about slow (though probably it is slow), but it surely eats a lot of RAM. Lots and lots of RAM.
- thebluesky 14y agoI'm willing to put up with a few hundred megs of RAM usage for a system which runs 100x faster...
- irahul 14y ago> Higher quality code. Java is easier to refactor than Ruby, which makes up for the lower language power. Let me rephrase: "It's easier in Java to rename identifiers than ruby, because my IDE does it for me." Now that's fine, but I don't see how do you conclude: Easier to rename identifiers => Higher quality code. How on earth? Easier to rename identifiers => Makes up for lower language power. What language deficiencies does renaming identifiers make up for? Other than renaming(which can be done for ruby, though it requires manual effort), there is no refactoring which Java does better than Ruby. > Actual concurrency! Am curious. Where in basic web development does concurrency help? As far as servers go, evented servers(thin, mongrel) will perform as good as, if not better, than a threaded server. And evented servers can handle much more concurrent requests than threaded servers. As far as concurrency at language level goes, very rarely have I needed to spawn a thread(I go for gevent) in the controller. Controller's job is to dispatch ASAP - everything else goes in the queue where you use EventMachine or gevent or whatever if you need concurrent processing. > Faster server spinup and incremental changes. Rails with 20 gems in development mode is super sluggish. Rails is more sluggish compared to "stop the world. I am compiling" Eclipse? > Better library ecosystem! > Better dependency management system (maven > rubygems) As long as we are just throwing out claims without backing them, ruby library and bundler/gem are 1000x better than mvn. > Better debuggers > Better profilers Not everyone is a fan of graphical everything. Going by this line of reasoning, Windows has better support for git because gui? > Easier deployment and ops environment(java -jar myjar, vs bundle install, ruby/passenger/unicorns) `java -jar myjar` starts your app server, your web server, minifies your css, js, migrates the db....? You can very well bundle the dependencies along with your app for rails, but I don't see why I would do it for a webapp. Also, your jar works only when you don't have java calling into native code. If you don't have native extensions, ruby is platform independent as well(i.e can be bundled). > Reasonable in-process metrics No ideas. What's that?
- sterwill 14y agoYour Java IDE also lets you move methods and fields, extract interfaces from concrete classes, push members up or down, find all references to a member (reliably), view inheritance relationships, and much more. And it can do all of those safely, warning you if you'll shadow another name. I wish I had that stuff in a Ruby IDE. I've used Eclipse for a long time, but not for JEE projects, and I don't see any "stop the world" behavior when it's compiling Java. Java compile jobs run at a low priority and rarely block another workspace job. If you want to save a file that's being compiled, Eclipse will let you and restart the build. Maybe you mean "stop the world I'm launching a JEE app?"
- swah 14y agoI'm kinda testing the same setup. There are a couple nice things, but one thing that hurts me coming from Python is that in Python an SQL row was just an dict with data, and I could change my schema (and add/remove entries from this object) and then return it as JSON quite easily. Now in Java/Dropwizard the tendency is to map from SQL rows to objects, then from objects to JSON. Which is a PITA, even more when your design/database changes too much. (The upside is that when you get some object, the data IS there).
- fizx 14y agoI tend to work more with document-like stores than SQL these days, so there may be more idiomatic solutions.... If you're complaining about having to update the fields in your object, I think thats kinda silly. You bought into the idea of static typing at some point, and now your data has type constraints. If you need need need flexibility you can of course make some field a Map<String, Object>. If you're complaining about boilerplate, you can at least automate the mapping with code like: class Util { public static <T> T resultSetToObject(ResultSet rs, Class<T> klass) { List<Map<String, Object>> rows = new ArrayList<Map<String, Object>>(); ResultSetMetaData metaData = resultSet.getMetaData(); int columnCount = metaData.getColumnCount(); while (resultSet.next()) { Map<String, Object> columns = new LinkedHashMap<String, Object>(); for (int i = 1; i <= columnCount; i++) { columns.put(metaData.getColumnLabel(i), resultSet.getObject(i)); } rows.add(columns); } return new ObjectMapper().convertValue(rows, klass) } }
- swah 14y agoYes, I wrote something similar (a Rowmap object)... But I have to admit it took me a while to realize that I could break that pattern.