Skip to content

Instantly share code, notes, and snippets.

@nahi
Created December 27, 2010 05:10
Show Gist options
  • Select an option

  • Save nahi/755878 to your computer and use it in GitHub Desktop.

Select an option

Save nahi/755878 to your computer and use it in GitHub Desktop.
httpclient is the fastest. benchmark.rb of JRuby can only measure elapsed time (at present)... Please see 'real' part.
% (git clone git://github.com/jruby/jruby.git; cd jruby)
% ant jar
% ant cext
% bin/jruby -S gem install curb
Building native extensions. This could take a while...
Successfully installed curb-0.7.9
1 gem installed
Installing ri documentation for curb-0.7.9...
Installing RDoc documentation for curb-0.7.9...
0% ruby ext_curb.rb http://www.google.co.jp/
Rehearsal ----------------------------------------------
curb 0.020000 0.010000 0.030000 ( 4.015826)
httpclient 0.060000 0.000000 0.060000 ( 5.078958)
------------------------------------- total: 0.090000sec
user system total real
curb 0.010000 0.010000 0.020000 ( 3.285568)
httpclient 0.030000 0.010000 0.040000 ( 3.738170)
0% jruby ext_curb.rb http://www.google.co.jp/
calling init (7f339eb75e0c)
Rehearsal ----------------------------------------------
curb 4.165000 0.000000 4.165000 ( 4.165000)
httpclient 4.748000 0.000000 4.748000 ( 4.748000)
------------------------------------- total: 8.913000sec
user system total real
curb 3.394000 0.000000 3.394000 ( 3.395000)
httpclient 2.613000 0.000000 2.613000 ( 2.613000)
0% ruby -v
ruby 1.9.3dev (2010-12-20 trunk 30271) [x86_64-linux]
0% jruby -v
jruby 1.6.0.dev (ruby 1.8.7 patchlevel 249) (2010-12-27 8cb2f98) (OpenJDK 64-Bit Server VM 1.6.0_20) [linux-amd64-java]
Here's the 2nd try patched JRuby. (RubyProcess.java.diff)
Measured numbers looks larger, but I'm not sure. Any thoughts?
0% jruby ext_curb.rb http://www.google.co.jp/
calling init (7fac54cdee0c)
Rehearsal ----------------------------------------------
curb 0.040000 0.000000 0.040000 ( 3.862000)
httpclient 0.570000 0.100000 0.670000 ( 4.149000)
------------------------------------- total: 0.710000sec
user system total real
curb 0.020000 0.020000 0.040000 ( 4.309000)
httpclient 0.220000 0.050000 0.270000 ( 3.467000)
0% ruby ext_curb.rb http://www.google.co.jp/
Rehearsal ----------------------------------------------
curb 0.010000 0.020000 0.030000 ( 4.126387)
httpclient 0.060000 0.000000 0.060000 ( 4.818490)
------------------------------------- total: 0.090000sec
user system total real
curb 0.000000 0.030000 0.030000 ( 4.287194)
httpclient 0.040000 0.010000 0.050000 ( 5.825304)
require 'rubygems'
require 'curl'
require 'httpclient'
require 'benchmark'
url = ARGV.shift
Benchmark.bmbm do |bm|
bm.report('curb') do
5.times do
Curl::Easy.http_get(url).body_str.size
end
end
bm.report('httpclient') do
c = HTTPClient.new
5.times do
c.get_content(url).size
end
end
end
diff --git a/src/org/jruby/RubyProcess.java b/src/org/jruby/RubyProcess.java
index 4d16468..ac6a105 100644
--- a/src/org/jruby/RubyProcess.java
+++ b/src/org/jruby/RubyProcess.java
@@ -29,6 +29,10 @@
***** END LICENSE BLOCK *****/
package org.jruby;
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadMXBean;
+import java.util.Map;
+
import com.kenai.constantine.platform.Errno;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
@@ -919,7 +923,35 @@ public class RubyProcess {
public static IRubyObject times(ThreadContext context, IRubyObject recv, Block unusedBlock) {
return times(context.getRuntime());
}
+ private static final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
public static IRubyObject times(Ruby runtime) {
+ if (threadBean.isCurrentThreadCpuTimeSupported()) {
+ long cpu = 0;
+ long user = 0;
+ // should not use this; this map is exposed for testing purpose.
+ Map<Object, RubyThread> map = runtime.getThreadService().getRubyThreadMap();
+ synchronized(map) {
+ for (Map.Entry<Object, RubyThread> entry : map.entrySet()) {
+ Object key = entry.getKey();
+ if (key == null || !(key instanceof Thread)) continue;
+ long id = ((Thread)key).getId();
+ long v = threadBean.getThreadCpuTime(id);
+ if (v != -1) {
+ cpu += v;
+ }
+ v = threadBean.getThreadUserTime(id);
+ if (v != -1) {
+ user += v;
+ }
+ }
+ }
+ double system_d = (cpu - user) / 1000000000.0;
+ double user_d = user / 1000000000.0;
+ RubyFloat zero = runtime.newFloat(0.0);
+ return RubyStruct.newStruct(runtime.getTmsStruct(),
+ new IRubyObject[] { RubyFloat.newFloat(runtime, user_d), RubyFloat.newFloat(runtime, system_d), zero, zero },
+ Block.NULL_BLOCK);
+ }
double currentTime = System.currentTimeMillis() / 1000.0;
double startTime = runtime.getStartTime() / 1000.0;
RubyFloat zero = runtime.newFloat(0.0);
@lucky
Copy link

lucky commented Dec 27, 2010

You're not accounting for latency.

@nahi
Copy link
Author

nahi commented Dec 27, 2010

luckythetourist: Yes. Do you have an idea how we can account network latency?
To be honest, all I can say from this test is:
"On a slow 3G network;

  • JRuby is faster for curb and httpclient,
  • httpclient is faster than curb on JRuby,
  • curb is faster than httpclient on CRuby,
  • httpclient + JRuby is faster than curb + CRuby"

@nahi
Copy link
Author

nahi commented Dec 27, 2010

FYI: Here's a script I created a few years ago: https://github.com/nahi/httpclient/blob/master/bench/bm.rb

@headius
Copy link

headius commented Dec 28, 2010

Latency should affect both implementations equally across repeat runs. For a "raw" bench, you could do something on a local network, but latency doesn't give either implentation or library an advantage or disadvantage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment