Java 使用jedis时,set(byte[],byte[])或set(String,String)哪个性能更好?

Java 使用jedis时,set(byte[],byte[])或set(String,String)哪个性能更好?,java,string,performance,serialization,redis,Java,String,Performance,Serialization,Redis,在我的笔记本电脑上,直接设置字符串的形式总是比设置字节[]好,即使使用序列化机制,当我使用绝地进行测试时也是如此。我很困惑,当调用jedisset(String,String)时,是否应该序列化String?如果出现了序列化机制,那么我在下面的SerializeUtil中所写的默认机制不是吗? 我的代码如下: public void testRedis() { long startTime = System.currentTimeMillis(); for

在我的笔记本电脑上,直接设置
字符串
的形式总是比设置
字节[]
好,即使使用
序列化机制
,当我使用
绝地
进行测试时也是如此。我很困惑,当调用jedis
set(String,String)
时,是否应该序列化
String
?如果出现了
序列化机制
,那么我在下面的
SerializeUtil
中所写的默认机制不是吗? 我的代码如下:

   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));
    }
有人能告诉我为什么吗

String
操作
+
替换为
StringBuilder
,现在
set(String,String)
仍然比其他方法更快

另一个问题是,当使用
set(byte[],byte[])
或只调用
String.getBytes[]
,是否有必要将
字符串序列化为字节?

set(byte[],byte[])效率更高,因为使用字符串时,它们会转换为byte[]在被编码到通讯缓冲区之前,在绝地内部

现在的问题是,在标准库中没有任何廉价的byte[]格式化例程,就像使用String一样。使用序列化类来格式化缓冲区太昂贵了。您需要的是字节[]的StringBuilder(即带有格式选项的ByteBuilder类)

大概是这样的: set(byte[],byte[])效率更高,因为当您使用String时,它们会在Jedis内部转换为byte[],然后再编码到通信缓冲区中

现在的问题是,在标准库中没有任何廉价的byte[]格式化例程,就像使用String一样。使用序列化类来格式化缓冲区太昂贵了。您需要的是字节[]的StringBuilder(即带有格式选项的ByteBuilder类)

大概是这样的:

我在SerializeUtil中进行序列化,因为我自己将字符串传输到字节[],这难道不会让事情变得更好吗?是的,但这一收益被以下事实抵消了:ByteArrayOutputStream的效率远远低于您应用+格式化字符串时使用的隐式StringBuilder。我在SerializeUtil中进行序列化,自从我自己将字符串传输到字节[]后,这难道不会让事情变得更好吗?是的,但这一收益被ByteArrayOutputStream的效率远远低于隐式StringBuilder的事实所抵消。隐式StringBuilder是在应用+格式化字符串时使用的。谢谢,我正在研究它,它很有帮助!您可以将Kryo用于字节[]格式化例程。。。我在我的笔记本电脑上用1000个线程并行测试了它,在一个事务中读/写的速度比字符串快3倍。谢谢,我正在研究它,它很有帮助!您可以将Kryo用于字节[]格式化例程。。。我在我的笔记本电脑上用1000个线程并行测试了它,在一个事务中读/写字符串的速度要快3倍。
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;
    }