创建特定大小(MB)的Java变量(字符串)

Ber*_*rez 14 java

我试图对一些代码进行基准测试.我正在通过套接字发送一个字符串消息.我想发送100KB,2MB和10MB字符串变量.有没有简单的方法来创建这些大小的变量?

目前我正在这样做.

private static String createDataSize(int msgSize) {
    String data = "a";
    while(data.length() < (msgSize*1024)-6) {
        data += "a";
    }
    return data;
}
Run Code Online (Sandbox Code Playgroud)

但这需要很长时间.有没有更好的办法?

更新:谢谢,我现在正在这样做.

/**
 * Creates a message of size @msgSize in KB.
 */
private static String createDataSize(int msgSize) {
    // Java chars are 2 bytes
    msgSize = msgSize/2;
    msgSize = msgSize * 1024;
    StringBuilder sb = new StringBuilder(msgSize);
    for (int i=0; i<msgSize; i++) {
        sb.append('a');
    }
    return sb.toString();
  }
Run Code Online (Sandbox Code Playgroud)

Chr*_*ung 35

您只需创建一个大字符数组即可.

char[] data = new char[1000000];
Run Code Online (Sandbox Code Playgroud)

如果您需要制作一个真实的String对象,您可以:

String str = new String(data);
Run Code Online (Sandbox Code Playgroud)

不要用于+=在循环中构建字符串.它具有O(n²)内存和时间使用,因为String对象是不可变的(因此每次调用时+=,都必须创建一个 String对象,在该过程中复制旧字符串的全部内容).

  • +1是唯一一个指出为什么他的代码很慢的人. (5认同)

Thi*_*ilo 23

直接使用char []或构建String.

char[] chars = new char[size];
Arrays.fill(chars, 'a');

String str = new String(chars);
Run Code Online (Sandbox Code Playgroud)

另请注意,一个char在内部使用两个字节.字符串将通过线路的长度取决于编码(字母a应该只是一个字节).

  • 或者你可以使用`Arrays.fill(chars,'a')`.:-) (3认同)

cle*_*tus 21

Java chars的大小为2个字节(16位无符号).所以,如果你想要2MB,你需要一百万个字符.您的代码有两个明显的问题:

  1. 反复呼叫length()是不必要的.将任何字符添加到Java中String,无论字符是什么,它的长度都会增加1.也许你会把它与字节大小混淆.这并不意味着; 和
  2. 您的代码存在巨大的内存碎片问题.

为了进一步解释(2),+Java中的字符串连接运算符()导致String创建一个新的,因为Java String是不可变的.所以:

String a = "a";
a += "b";
Run Code Online (Sandbox Code Playgroud)

实际意味着:

String a = "a";
String a = a + "b";
Run Code Online (Sandbox Code Playgroud)

这有时会使前C++程序员感到困惑,因为字符串在C++中的工作方式不同.

因此,您的代码实际上为一百万的消息大小分配了一百万个字符串.只保留最后一个.其他是垃圾,将被清理,但没有必要.

更好的版本是:

private static String createDataSize(int msgSize) {
  StringBuilder sb = new StringBuilder(msgSize);
  for (int i=0; i<msgSize; i++) {
    sb.append('a');
  }
  return sb.toString();
}
Run Code Online (Sandbox Code Playgroud)

关键的区别在于:

  1. A StringBuilder是可变的,因此不需要在每次更改时重新分配; 和
  2. StringBuilder被预分配给这个代码示例中的权利的大小.

注意:精明的人可能已经注意到我已经完成了:

sb.append('a');
Run Code Online (Sandbox Code Playgroud)

而不是:

sb.append("a");
Run Code Online (Sandbox Code Playgroud)

'a'当然是一个单一的角色,"a"是一个String.你可以使用这种情况.

但是,它并不那么简单,因为它取决于字节的编码方式.通常,除非您指定它,否则它将使用UTF8,它是可变宽度字符.因此,一百万个字符的大小可能在1MB到4MB之间,具体取决于您最终对其进行编码,而您的问题不包含详细信息.

如果您需要特定大小的数据并且数据无关紧要,我的建议是简单地使用byte正确大小的数组.