001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.codec; 019 020import static org.junit.Assert.assertArrayEquals; 021import static org.junit.Assert.assertTrue; 022 023import java.io.ByteArrayInputStream; 024import java.io.ByteArrayOutputStream; 025import java.io.IOException; 026import org.apache.hadoop.hbase.Cell; 027import org.apache.hadoop.hbase.CellScanner; 028import org.apache.hadoop.hbase.KeyValue; 029import org.apache.hadoop.hbase.io.CellOutputStream; 030import org.apache.hadoop.hbase.util.Bytes; 031import org.apache.yetus.audience.InterfaceAudience; 032import org.slf4j.Logger; 033import org.slf4j.LoggerFactory; 034 035/** 036 * Do basic codec performance eval. 037 */ 038@InterfaceAudience.Public 039public class CodecPerformance { 040 /** @deprecated LOG variable would be made private. since 1.2, remove in 3.0 */ 041 @Deprecated 042 public static final Logger LOG = LoggerFactory.getLogger(CodecPerformance.class); 043 044 static Cell[] getCells(final int howMany) { 045 Cell[] cells = new Cell[howMany]; 046 for (int i = 0; i < howMany; i++) { 047 byte[] index = Bytes.toBytes(i); 048 KeyValue kv = new KeyValue(index, Bytes.toBytes("f"), index, index); 049 cells[i] = kv; 050 } 051 return cells; 052 } 053 054 static int getRoughSize(final Cell[] cells) { 055 int size = 0; 056 for (Cell c : cells) { 057 size += c.getRowLength() + c.getFamilyLength() + c.getQualifierLength() + c.getValueLength(); 058 size += Bytes.SIZEOF_LONG + Bytes.SIZEOF_BYTE; 059 } 060 return size; 061 } 062 063 static byte[] runEncoderTest(final int index, final int initialBufferSize, 064 final ByteArrayOutputStream baos, final CellOutputStream encoder, final Cell[] cells) 065 throws IOException { 066 long startTime = System.currentTimeMillis(); 067 for (int i = 0; i < cells.length; i++) { 068 encoder.write(cells[i]); 069 } 070 encoder.flush(); 071 LOG.info("" + index + " encoded count=" + cells.length + " in " 072 + (System.currentTimeMillis() - startTime) + "ms for encoder " + encoder); 073 // Ensure we did not have to grow the backing buffer. 074 assertTrue(baos.size() < initialBufferSize); 075 return baos.toByteArray(); 076 } 077 078 static Cell[] runDecoderTest(final int index, final int count, final CellScanner decoder) 079 throws IOException { 080 Cell[] cells = new Cell[count]; 081 long startTime = System.currentTimeMillis(); 082 for (int i = 0; decoder.advance(); i++) { 083 cells[i] = decoder.current(); 084 } 085 LOG.info("" + index + " decoded count=" + cells.length + " in " 086 + (System.currentTimeMillis() - startTime) + "ms for decoder " + decoder); 087 // Ensure we did not have to grow the backing buffer. 088 assertTrue(cells.length == count); 089 return cells; 090 } 091 092 static void verifyCells(final Cell[] input, final Cell[] output) { 093 assertArrayEquals(input, output); 094 } 095 096 static void doCodec(final Codec codec, final Cell[] cells, final int cycles, final int count, 097 final int initialBufferSize) throws IOException { 098 byte[] bytes = null; 099 Cell[] cellsDecoded = null; 100 for (int i = 0; i < cycles; i++) { 101 ByteArrayOutputStream baos = new ByteArrayOutputStream(initialBufferSize); 102 Codec.Encoder encoder = codec.getEncoder(baos); 103 bytes = runEncoderTest(i, initialBufferSize, baos, encoder, cells); 104 } 105 for (int i = 0; i < cycles; i++) { 106 ByteArrayInputStream bais = new ByteArrayInputStream(bytes); 107 Codec.Decoder decoder = codec.getDecoder(bais); 108 cellsDecoded = CodecPerformance.runDecoderTest(i, count, decoder); 109 } 110 verifyCells(cells, cellsDecoded); 111 } 112 113 public static void main(String[] args) throws IOException { 114 // How many Cells to encode/decode on each cycle. 115 final int count = 100000; 116 // How many times to do an operation; repeat gives hotspot chance to warm up. 117 final int cycles = 30; 118 119 Cell[] cells = getCells(count); 120 int size = getRoughSize(cells); 121 int initialBufferSize = 2 * size; // Multiply by 2 to ensure we don't have to grow buffer 122 123 // Test KeyValue codec. 124 doCodec(new KeyValueCodec(), cells, cycles, count, initialBufferSize); 125 doCodec(new CellCodec(), cells, cycles, count, initialBufferSize); 126 doCodec(new MessageCodec(), cells, cycles, count, initialBufferSize); 127 } 128}