diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Revision.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Revision.java
index 26634e3..a6ee34c 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Revision.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Revision.java
@@ -27,6 +27,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
  */
 public final class Revision implements CacheValue {
 
+    //Extra 2 for those cases where counter or clusterId is 2 digit
+    final static int REV_STRING_SIZE = Revision.newRevision(0).toString().length() + 2;
+
     static final int SHALLOW_MEMORY_USAGE = 32;
 
     private static volatile long lastTimestamp;
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionVector.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionVector.java
index f2f327b..58e9ef7 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionVector.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionVector.java
@@ -27,11 +27,9 @@ import javax.annotation.Nonnull;
 
 import com.google.common.collect.AbstractIterator;
 import com.google.common.collect.Iterators;
-import com.google.common.collect.Lists;
 import com.google.common.collect.PeekingIterator;
 import com.google.common.collect.Sets;
 import com.google.common.primitives.Ints;
-
 import org.apache.jackrabbit.oak.cache.CacheValue;
 import org.apache.jackrabbit.oak.plugins.document.util.Utils;
 
@@ -57,6 +55,8 @@ public final class RevisionVector implements Iterable<Revision>, Comparable<Revi
 
     private final Revision[] revisions;
 
+    private int hash;
+
     private RevisionVector(@Nonnull Revision[] revisions,
                            boolean checkUniqueClusterIds,
                            boolean sort) {
@@ -320,12 +320,16 @@ public final class RevisionVector implements Iterable<Revision>, Comparable<Revi
      * @return a string representation of this revision vector.
      */
     public String asString() {
-        StringBuilder sb = new StringBuilder();
-        String comma = "";
-        for (Revision r : revisions) {
-            sb.append(comma);
-            comma = ",";
-            r.toStringBuilder(sb);
+        int len = revisions.length;
+        if (len == 0) {
+            return "";
+        }
+        StringBuilder sb = new StringBuilder(len * Revision.REV_STRING_SIZE + len - 1);
+        for (int i = 0; i < len; i++) {
+            if (i > 0) {
+                sb.append(',');
+            }
+            revisions[i].toStringBuilder(sb);
         }
         return sb.toString();
     }
@@ -339,9 +343,10 @@ public final class RevisionVector implements Iterable<Revision>, Comparable<Revi
      * @throws IllegalArgumentException if the string is malformed
      */
     public static RevisionVector fromString(String s) {
-        List<Revision> revisions = Lists.newArrayListWithCapacity(3);
-        for (String str : s.split(",")) {
-            revisions.add(Revision.fromString(str));
+        String[] list = s.split(",");
+        Revision[] revisions = new Revision[list.length];
+        for (int i = 0; i < list.length; i++) {
+            revisions[i] = Revision.fromString(list[i]);
         }
         return new RevisionVector(revisions);
     }
@@ -446,9 +451,12 @@ public final class RevisionVector implements Iterable<Revision>, Comparable<Revi
     }
 
     @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof RevisionVector) {
-            RevisionVector other = (RevisionVector) obj;
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        if (o instanceof RevisionVector) {
+            RevisionVector other = (RevisionVector) o;
             return Arrays.equals(revisions, other.revisions);
         }
         return false;
@@ -456,7 +464,10 @@ public final class RevisionVector implements Iterable<Revision>, Comparable<Revi
 
     @Override
     public int hashCode() {
-        return Arrays.hashCode(revisions);
+        if (hash == 0){
+            hash = Arrays.hashCode(revisions);
+        }
+        return hash;
     }
 
     //-------------------------< internal >-------------------------------------
diff --git oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionVectorTest.java oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionVectorTest.java
index ebe11cb..d99b9c7 100644
--- oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionVectorTest.java
+++ oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionVectorTest.java
@@ -382,4 +382,16 @@ public class RevisionVectorTest {
         rv = rv.update(r12);
         assertEquals(new RevisionVector(br11, r12), rv.asBranchRevision(1));
     }
+
+    @Test
+    public void fromString() throws Exception{
+        RevisionVector rv = new RevisionVector(
+                new Revision(1, 0, 1),
+                new Revision(2, 0, 2)
+        );
+
+        String rvstr = rv.asString();
+        RevisionVector rvFromStr = RevisionVector.fromString(rvstr);
+        assertEquals(rv, rvFromStr);
+    }
 }
