1

On my laptop, set String directly is always proformace better than set byte[], even with Serialization mechanism when I test with Jedis. I am confused that if String should be serialized when call jedis set(String, String)? If Serialization mechanism happend, isn't is the default mechaism as I write in my SerializeUtil below? My code is below:

   public void testRedis() {

        long startTime = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            StringBuilder sb = new StringBuilder(str);
            sb.append(i);
            jedis.set(sb.toString(), value);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("default: " + (endTime - startTime));

        startTime = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            StringBuilder sb = new StringBuilder(str);
            sb.append(i);
            jedis.set(sb.toString().getBytes(), value.getBytes());
        }
        endTime = System.currentTimeMillis();
        System.out.println("byte: " + (endTime - startTime));

        startTime = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            StringBuilder sb = new StringBuilder(str);
            sb.append(i);
            jedis.set(SerializeUtil.serDefaultString(sb.toString()), SerializeUtil.serDefaultString(value));
        }
        endTime = System.currentTimeMillis();
        System.out.println("default ser: " + (endTime - startTime));

        startTime = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            StringBuilder sb = new StringBuilder(str);
            sb.append(i);
            jedis.set(SerializeUtil.serUTFString(sb.toString()), SerializeUtil.serUTFString(value));
        }
        endTime = System.currentTimeMillis();
        System.out.println("utf ser: " + (endTime - startTime));
    }

Maybe SerializeUtil is need :

public static byte[] serDefaultString(String data) {

        byte[] result = null;

        ObjectOutputStream oos = null;
        ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
        try {
            oos = new ObjectOutputStream(byteArray);
            try {
                oos.writeObject(data);
                oos.flush();
                result = byteArray.toByteArray();
            } finally {
                oos.close();
            }
        } catch(IOException e) {
            e.printStackTrace();
        }

        return result;
    }

public static byte[] serUTFString(String data) {

        byte[] result = null;
        ObjectOutputStream oos = null;
        ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
        try {
            oos = new ObjectOutputStream(byteArray);
            try {
                oos.writeUTF(data);
                oos.flush();
                result = byteArray.toByteArray();
            } finally {
                oos.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

Is anyone can tell me why?

Replace String operation + to StringBuilder, now set(String, String) is still faster than other approach.

Another question, Is it necessary to serialize String to bytes when work with set(byte[], byte[]) or just call String.getBytes[] ?

znlyj
  • 1,109
  • 3
  • 14
  • 34
  • http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java – Kyle May 25 '13 at 17:29
  • Thanks, I am studying it and it's helpful! – znlyj May 26 '13 at 01:19
  • You could use Kryo for byte[] formatting routine... I tested it on my laptop with 1000 thread in parallel and could 3 time faster than string read/write in a single transaction. – Pinkoo Sep 17 '18 at 03:43

1 Answers1

1

set( byte[], byte[] ) is more efficient because, when you use String, they are converted in byte[] internally in Jedis before being encoded in the communication buffer.

Now, the problem is you do not have any cheap byte[] formatting routines in the standard library like you have with String. Using serialization classes to just format a buffer is too expensive. What you would need is a StringBuilder for byte[] (i.e. a ByteBuilder class with formatting options).

Something like this: https://code.google.com/p/coding4play/source/browse/trunk/Server/src/gameserver/util/ByteBuilder.java?r=63

Didier Spezia
  • 70,911
  • 12
  • 189
  • 154
  • I do serialization in my SerializeUtil, doesn't it make things better since I transfer String to byte[] by myself? – znlyj May 25 '13 at 15:00
  • Yes, but this gain is offset by the fact ByteArrayOutputStream is much less efficient than the implicit StringBuilder which is used when you apply + to format your strings. – Didier Spezia May 25 '13 at 17:22