I rather prefer another style of code. Instead of

--

        String last = lastString;
        if (last == null) {
            try {
                if (getRuntime().is1_9()) {
                    lastString = last = new String(value.getUnsafeBytes(), 
value.begin(), value.length(), getEncoding().toString());
                } else {
                    lastString = last = 
RubyEncoding.decodeUTF8(value.getUnsafeBytes(), value.begin(), value.length());
                }
            } catch (UnsupportedEncodingException uee) {
                lastString = last = value.toString();
            }
        }
        return last;

--

Why not the code below?


--

        if (lastString != null) return lastString;
        try {
            if (getRuntime().is1_9()) {
                lastString = new String(value.getUnsafeBytes(), value.begin(), 
value.length(), getEncoding().toString());
            } else {
                lastString = RubyEncoding.decodeUTF8(value.getUnsafeBytes(), 
value.begin(), value.length());
            }
        } catch (UnsupportedEncodingException uee) {
            lastString = value.toString();
        }
        return lastString;

--

This avoids deep nested code.

Rodrigo.

On 17-01-2011 01:28, Charles Oliver Nutter (JIRA) wrote:
Consider caching last toString result in RubyString, for performance
--------------------------------------------------------------------

                  Key: JRUBY-5370
                  URL: http://jira.codehaus.org/browse/JRUBY-5370
              Project: JRuby
           Issue Type: Improvement
           Components: Core Classes/Modules
     Affects Versions: JRuby 1.6RC1
             Reporter: Charles Oliver Nutter


In playing with ways to speed up JRuby to Java invocation, I added a cache for 
the toString result of a RubyString. RubyString normally causes a new String 
object to be created for every call. In many cases, these calls are repeatedly 
passed the same String object. By caching that String and flushing it on 
modification, we can end up with much better call performance.

Here's the perf difference:

{noformat}
BEFORE:
~/projects/jruby➔ jruby -rbenchmark -e "10.times { puts Benchmark.measure { 
str = 'foo' * 10; dashe = Java::DashE; 1_000_000.times { dashe.foo(str) } } }"
   1.170000   0.000000   1.170000 (  1.058000)
   0.695000   0.000000   0.695000 (  0.695000)
   0.694000   0.000000   0.694000 (  0.694000)
   0.691000   0.000000   0.691000 (  0.691000)
   0.695000   0.000000   0.695000 (  0.696000)
   0.685000   0.000000   0.685000 (  0.685000)
   0.690000   0.000000   0.690000 (  0.690000)
   0.725000   0.000000   0.725000 (  0.725000)
   0.725000   0.000000   0.725000 (  0.725000)
   0.692000   0.000000   0.692000 (  0.692000)

AFTER:
~/projects/jruby➔ jruby -rbenchmark -e "10.times { puts Benchmark.measure { 
str = 'foo' * 10; dashe = Java::DashE; 1_000_000.times { dashe.foo(str) } } }"
   0.797000   0.000000   0.797000 (  0.684000)
   0.332000   0.000000   0.332000 (  0.332000)
   0.329000   0.000000   0.329000 (  0.329000)
   0.332000   0.000000   0.332000 (  0.332000)
   0.320000   0.000000   0.320000 (  0.320000)
   0.320000   0.000000   0.320000 (  0.320000)
   0.357000   0.000000   0.357000 (  0.357000)
   0.350000   0.000000   0.350000 (  0.350000)
   0.321000   0.000000   0.321000 (  0.321000)
   0.324000   0.000000   0.324000 (  0.324000)
{noformat}

And here's the patch:

{noformat}
diff --git a/src/org/jruby/RubyString.java b/src/org/jruby/RubyString.java
index bc8377f..04ec6f3 100644
--- a/src/org/jruby/RubyString.java
+++ b/src/org/jruby/RubyString.java
@@ -126,6 +126,8 @@ public class RubyString extends RubyObject implements 
EncodingCapable {

      private RString rstring;

+    private String lastString;
+
      public static RubyClass createStringClass(Ruby runtime) {
          RubyClass stringClass = runtime.defineClass("String", 
runtime.getObject(), STRING_ALLOCATOR);
          runtime.setString(stringClass);
@@ -649,7 +651,19 @@ public class RubyString extends RubyObject implements 
EncodingCapable {

      @Override
      public String toString() {
-        return value.toString();
+        String last = lastString;
+        if (last == null) {
+            try {
+                if (getRuntime().is1_9()) {
+                    lastString = last = new String(value.getUnsafeBytes(), 
value.begin(), value.length(), getEncoding().toString());
+                } else {
+                    lastString = last = 
RubyEncoding.decodeUTF8(value.getUnsafeBytes(), value.begin(), value.length());
+                }
+            } catch (UnsupportedEncodingException uee) {
+                lastString = last = value.toString();
+            }
+        }
+        return last;
      }

      /** rb_str_dup
@@ -731,6 +745,8 @@ public class RubyString extends RubyObject implements 
EncodingCapable {
          if (!isTaint()&&  getRuntime().getSafeLevel()>= 4) {
              throw getRuntime().newSecurityError("Insecure: can't modify 
string");
          }
+
+        lastString = null;
      }

      private final void modifyCheck(byte[] b, int len) {
@@ -7292,17 +7308,7 @@ public class RubyString extends RubyObject implements 
EncodingCapable {
      @Override
      public Object toJava(Class target) {
          if (target.isAssignableFrom(String.class)) {
-            try {
-                // 1.9 support for encodings
-                // TODO: Fix charset use for JRUBY-4553
-                if (getRuntime().is1_9()) {
-                    return new String(value.getUnsafeBytes(), value.begin(), 
value.length(), getEncoding().toString());
-                }
-
-                return RubyEncoding.decodeUTF8(value.getUnsafeBytes(), 
value.begin(), value.length());
-            } catch (UnsupportedEncodingException uee) {
-                return toString();
-            }
+            return toString();
          } else if (target.isAssignableFrom(ByteList.class)) {
              return value;
          } else {
{noformat}



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email


Reply via email to