Title: [927] trunk: Add java_inline library to jruby_extras.
- Revision
- 927
- Author
- headius
- Date
- 2008-03-07 12:13:45 -0500 (Fri, 07 Mar 2008)
Log Message
Add java_inline library to jruby_extras.
Added Paths
Diff
Added: trunk/java_inline/lib/java_inline.rb (0 => 927)
--- trunk/java_inline/lib/java_inline.rb (rev 0)
+++ trunk/java_inline/lib/java_inline.rb 2008-03-07 17:13:45 UTC (rev 927)
@@ -0,0 +1,101 @@
+require 'inline'
+require 'java'
+
+# Add the inline cache dir to CLASSPATH
+$CLASSPATH << Inline.directory
+
+module Inline
+
+ # A Java builder for RubyInline. Provides the basic methods needed to
+ # allow assembling a set of Java methods that compile into a class and
+ # get bound to the same names in the containing module.
+ class Java
+ JFile = java.io.File
+ import javax.tools.ToolProvider
+ import javax.tools.SimpleJavaFileObject
+ import javax.tools.StandardLocation
+
+ def initialize(mod)
+ @context = mod
+ @src = ""
+ @imports = []
+ @sigs = []
+ end
+
+ def load_cache
+ false
+ end
+
+ # Set the package to use for the Java class being generated, as in
+ # builder.package "org.foo.bar"
+ def package(pkg)
+ @pkg = pkg
+ end
+
+ # Add an "import" line with the given class, as in
+ # builder.import "java.util.ArrayList". The imports will be composed
+ # into an appropriate block of code and added to the top of the source.
+ def import(cls)
+ @imports << cls
+ end
+
+ # Add a Java method to the built Java source. This expects the method to
+ # be public and static, so it can be called as a function.
+ def java(src)
+ @src << src << "\n"
+ signature = src.match(/public static\W+(\w+)\W+([a-zA-Z0-9_]+)\((.*)\)/)
+ raise "Could not parse method signature" unless signature
+ @sigs << [signature[1], signature[2], signature[3]]
+ end
+
+ def build
+ compiler = ToolProvider.system_java_compiler
+ file_mgr = compiler.get_standard_file_manager(nil, nil, nil)
+ file_mgr.set_location(StandardLocation::CLASS_OUTPUT, [JFile.new(Inline.directory)])
+
+ if @pkg
+ directory = "#{Inline.directory}/[EMAIL PROTECTED]('.', '/')}"
+ unless File.directory? directory then
+ $stderr.puts "NOTE: creating #{directory} for RubyInline" if $DEBUG
+ FileUtils.mkdir_p directory
+ end
+
+ @name = "[EMAIL PROTECTED]"
+ @load_name = "[EMAIL PROTECTED]@name}"
+ filename = "#{directory}/[EMAIL PROTECTED]"
+
+ imports = "import " + @imports.join(";\nimport ") + ";" if @imports.size > 0
+ full_src = "
+ package [EMAIL PROTECTED];
+ #{imports}
+ public class [EMAIL PROTECTED] {
+ [EMAIL PROTECTED]
+ }
+ "
+ else
+ @load_name = @name = "[EMAIL PROTECTED]"
+ filename = "#{Inline.directory}/[EMAIL PROTECTED]"
+
+ imports = "import " + @imports.join(";\nimport ") + ";" if @imports.size > 0
+ full_src = "
+ #{imports}
+ public class [EMAIL PROTECTED] {
+ [EMAIL PROTECTED]
+ }
+ "
+ end
+
+ File.open(filename, "w") {|file| file.write(full_src)}
+ file_objs = file_mgr.get_java_file_objects_from_strings([filename])
+
+ compiler.get_task(nil, file_mgr, nil, nil, nil, file_objs).call
+ file_mgr.close
+ end
+
+ def load
+ @sigs.each do |sig|
+ @context.module_eval "const_set :[EMAIL PROTECTED], ::Java::[EMAIL PROTECTED]; p '[EMAIL PROTECTED]'; def #{sig[1]}(*args); [EMAIL PROTECTED](*args); end"
+ end
+ end
+ end
+end
Added: trunk/java_inline/samples/fastmath.rb (0 => 927)
--- trunk/java_inline/samples/fastmath.rb (rev 0)
+++ trunk/java_inline/samples/fastmath.rb 2008-03-07 17:13:45 UTC (rev 927)
@@ -0,0 +1,56 @@
+require 'rubygems'
+require 'inline'
+require 'java_inline'
+require 'benchmark'
+
+class FastMath
+ def factorial_ruby(n)
+ f = 1
+ n.downto(2) { |x| f *= x }
+ return f
+ end
+
+ def fib_ruby(n)
+ if n < 2
+ n
+ else
+ fib_ruby(n - 2) + fib_ruby(n - 1)
+ end
+ end
+
+ inline :Java do |builder|
+ builder.package "org.jruby.test"
+ builder.java "
+ public static long factorial_java(int max) {
+ int i=max, result=1;
+ while (i >= 2) { result *= i--; }
+ return result;
+ }
+ "
+
+ builder.java "
+ public static int fib_java(int n) {
+ if (n < 2) return n;
+
+ return fib_java(n - 2) + fib_java(n - 1);
+ }
+ "
+ end
+
+ def bench
+ require 'benchmark'
+
+ Benchmark.bm(30) do |bm|
+ end
+ end
+end
+
+math = FastMath.new
+
+Benchmark.bmbm(30) {|bm|
+ 5.times { bm.report("factorial_ruby") { 30000.times { math.factorial_ruby(30) } } }
+ 5.times { bm.report("factorial_java") { 30000.times { math.factorial_java(30) } } }
+ 5.times { bm.report("fib_ruby(35)") { math.fib_ruby(30) } }
+ 5.times { bm.report("fib_java(35)") { math.fib_java(30) } }
+}
+
_______________________________________________
Jruby-extras-devel mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/jruby-extras-devel