[ 
https://issues.apache.org/jira/browse/HBASE-19684?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16310390#comment-16310390
 ] 

BELUGA BEHR commented on HBASE-19684:
-------------------------------------

[~mdrob] If you want to play that game... HA! :)

{code}
  @State(Scope.Thread)
  public static class Data
  {
    Random r = new Random();
    String a;
    Long b;

    @Setup(Level.Trial)
    public void setup()
    {
      a = Long.toHexString(r.nextLong());
      b = Long.MIN_VALUE + 1L;
    }
  }

  @Benchmark
  public String testStringBuilder(Data data)
  {
    return (new StringBuilder(data.a.length() + 
21).append(data.a).append('_').append(data.b).toString());
  }

  @Benchmark
  public String testConcatOperator(Data data)
  {
    return data.a + '_' + data.b;
  }
{code}

{code}
# Run complete. Total time: 00:13:28

Benchmark                             Mode  Cnt         Score        Error  
Units
BenchmarkStrings.testConcatOperator  thrpt  200   7852314.219 ± 154534.037  
ops/s
BenchmarkStrings.testStringBuilder   thrpt  200  10360674.186 ±  22605.073  
ops/s
{code}

Here we can see that the explicit StringBuilder is faster, as I would expect.  
This is because I am testing, not with random Long values, but with a constant 
Long value, which when turned into a String, has a long string length (20 
characters).  So in TestStringBuilder, I account for these 20 characters, plus 
1 character for the underscore.  Therefore, everything fits nicely into one, 
pre-allocated, buffer.

{quote}
public StringBuilder(String str)
Constructs a string builder initialized to the contents of the specified 
string. The initial capacity of the string builder is 16 plus the length of the 
string argument.
{quote}

So, in the testConcatOperator method, the 16-byte buffer must be expanded 
(which includes the normal operation of allocated a new buffer and copying the 
old contents into it) to fit the 21 characters that are required to represent 
this Long value + one underscore.

> BlockCacheKey toString Performance
> ----------------------------------
>
>                 Key: HBASE-19684
>                 URL: https://issues.apache.org/jira/browse/HBASE-19684
>             Project: HBase
>          Issue Type: Improvement
>          Components: hbase
>    Affects Versions: 3.0.0
>            Reporter: BELUGA BEHR
>            Assignee: BELUGA BEHR
>            Priority: Trivial
>         Attachments: HBASE-19684.1.patch, HBASE-19684.2.patch
>
>
> {code:titile=BlockCacheKey.java}
>   @Override
>   public String toString() {
>     return String.format("%s_%d", hfileName, offset);
>   }
> {code}
> I found through bench-marking that the following code is 10x faster.
> {code:titi\le=BlockCacheKey.java}
>   @Override
>   public String toString() {
>     return hfileName.concat("_").concat(Long.toString(offset));
>   }
> {code}
> Normally it wouldn't matter for a _toString()_ method, but this is comes into 
> play because {{MemcachedBlockCache}} uses it.
> {code:title=MemcachedBlockCache.java}
>   @Override
>   public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf) {
>     if (buf instanceof HFileBlock) {
>       client.add(cacheKey.toString(), MAX_SIZE, (HFileBlock) buf, tc);
>     } else {
>       if (LOG.isDebugEnabled()) {
>         LOG.debug("MemcachedBlockCache can not cache Cacheable's of type "
>             + buf.getClass().toString());
>       }
>     }
>   }
> {code}



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to