这个Java算法如何更快
我有一个循环,它将布尔链接列表拆分8位,并返回缓冲区中每个字节的ASCII值。函数返回字符串缓冲区 如果LinkedList的大小很大,则此代码非常慢。我尝试用一个简单的循环来更改这个Java算法如何更快,java,algorithm,binary,linked-list,ascii,Java,Algorithm,Binary,Linked List,Ascii,我有一个循环,它将布尔链接列表拆分8位,并返回缓冲区中每个字节的ASCII值。函数返回字符串缓冲区 如果LinkedList的大小很大,则此代码非常慢。我尝试用一个简单的循环来更改迭代器,但仍然很慢 这个算法怎么可能真的很快?也许是多线程 注意:linkedList的大小并不总是可以被8整除 public String toString(){ String buffer = ""; String output = ""; LinkedList&
迭代器,但仍然很慢
这个算法怎么可能真的很快?也许是多线程
注意:linkedList的大小并不总是可以被8整除
public String toString(){
String buffer = "";
String output = "";
LinkedList<Boolean> bits = this.bits;
for(Iterator it = this.bits.iterator(); it.hasNext();){
if(buffer.length() >= 8){
output += (char)Integer.parseInt(buffer, 2);
buffer = "";
}
buffer += ((Boolean)it.next() == false) ? "0" : "1";
}
if(buffer != "")
output += (char)Integer.parseInt(buffer, 2);
return output;
}
公共字符串toString(){
字符串缓冲区=”;
字符串输出=”;
LinkedList位=this.bits;
for(Iterator it=this.bits.Iterator();it.hasNext();){
if(buffer.length()>=8){
输出+=(字符)整数.parseInt(缓冲区,2);
缓冲区=”;
}
buffer+=((布尔)it.next()==false)?“0”:“1”;
}
如果(缓冲区!=“”)
输出+=(字符)整数.parseInt(缓冲区,2);
返回输出;
}
字符串连接速度较慢,尤其是对于大型列表(因为字符串是不可变的,所以必须对其进行复制,这需要一些时间,而且每个复制也需要更多的空间)。使用StringBuilder
而不是要附加到的String
。换句话说:buffer
和output
应该是StringBuilder
实例。这些建议将为您提供足够的性能,同时保持代码简单易读。首先使用这些更改进行测试,如果不满足您的性能要求,则慢慢引入其他答案中建议的优化技术
使用位集
而不是链接列表
使用StringBuilder输出代码>而不是字符串输出代码>
使用StringBuilder缓冲区代码>而不是字符串缓冲区代码>
使用Integer.valueOf()
而不是Integer.parseInt
valueOf
对128以下的值使用缓存
使用StringBuilder
初始化为预期输出容量:
StringBuilder out = new StringBuilder(bits.size() / 8 + 1);
使用按位操作而不是parseInt()
,类似这样:
int i = 0;
int c = 0;
for(Boolean b: bits){
if (i > 0 && i % 8 == 0){
out.append((char) c);
c = 0;
}
c = (c << 1) | (b ? 1 : 0);
i++;
}
out.append((char) c); // Not sure about the desired behaviour here
inti=0;
int c=0;
for(布尔b:位){
如果(i>0&&i%8==0){
out.append((char)c);
c=0;
}
c=(c试着将缓冲区保持为int
buffer = buffer << 1 + (((Boolean)it.next() == false) ? 0 : 1);
还可以使用StringBuilder
进行输出。这在这里是一个小改动,但总是有一点。尝试以下操作:
StringBuilder b = new StringBuilder();
int ch = 0;
int n = 0;
for (Boolean bit : bits) {
ch <<= 1;
if (bit) {
ch++;
}
if (++n == 8) {
b.append((char)ch);
n = 0;
ch = 0;
}
}
if (n > 0) {
b.append((char)ch);
}
System.out.println(b.toString());
StringBuilder b=新的StringBuilder();
int ch=0;
int n=0;
for(布尔位:位){
ch对于缓冲区和输出变量,使用StringBuffer或stringBuilder而不是String
字符串变量是不可变的,因此每个操作都会在堆中创建一个新实例,而StringBuilder和StringBuffer则不是。正如其他人建议的那样-使用位集。对于其余的,我认为下面的方法非常有效:
public String toString() {
char[] bytes = new char[bits.size() / 8 + ((bits.size() % 8 > 0) ? 1 : 0)];
int bitCounter = 0;
int word = 0;
int byteCounter = 0;
for (boolean b : bits) {
word = (word << 1) | (b ? 1 : 0);
if (bitCounter == 7) {
bytes[byteCounter] = (char) word;
++byteCounter;
bitCounter = 0;
word = 0;
} else {
++bitCounter;
} // else
} // foreach
bytes[byteCounter] = (char) word;
return new String(bytes);
} // toString() method
公共字符串toString(){
char[]bytes=新字符[bits.size()/8+((bits.size()%8>0)?1:0)];
int位计数器=0;
int字=0;
int字节计数器=0;
for(布尔b:位){
单词=(单词0)?1:0;
如果(大小==0){
返回“”;
}//如果
字符[]字节=新字符[大小];
int位计数器=0;
int字=0;
for(布尔b:位){
如果(位计数器%8==0
&&位计数器>0){
字节[(位计数器-1)/8]=(字符)字;
字=0;
}//如果
单词=(word最后一个非8位缓冲区将转换为ascii值,该值将连接到输出。@beny23 OP正在用字符串创建整数,他可以使用ValueOfWaw,我用代码压缩的演示文件用了1分钟多,而你的用了不到1秒。我只是不明白你为什么要用I%8!=1。模c应该是2,3,4..?里面的代码必须在字符串生成器中附加非8位字符值。@Pier alexandreBouchard:是的,这段代码包含一个off by one错误,等等。@Pier alexandreBouchard:现在似乎很好。我做了几个测试,但似乎还可以。我谦虚地相信我下面的代码更有效,因为它没有使用StringBuilder。我谦恭地建议您在第一个代码示例中使用buffer*2
,或者buffer=(buffer=)
public String toString() {
char[] bytes = new char[bits.size() / 8 + ((bits.size() % 8 > 0) ? 1 : 0)];
int bitCounter = 0;
int word = 0;
int byteCounter = 0;
for (boolean b : bits) {
word = (word << 1) | (b ? 1 : 0);
if (bitCounter == 7) {
bytes[byteCounter] = (char) word;
++byteCounter;
bitCounter = 0;
word = 0;
} else {
++bitCounter;
} // else
} // foreach
bytes[byteCounter] = (char) word;
return new String(bytes);
} // toString() method
public String toString() {
int size = bits.size() / 8 + ((bits.size() % 8 > 0) ? 1 : 0);
if (size == 0) {
return "";
} // if
char[] bytes = new char[size];
int bitCounter = 0;
int word = 0;
for (boolean b : bits) {
if (bitCounter % 8 == 0
&& bitCounter > 0) {
bytes[(bitCounter - 1) / 8] = (char) word;
word = 0;
} // if
word = (word << 1) | (b ? 1 : 0);
++bitCounter;
} // foreach
bytes[size - 1] = (char) word;
return new String(bytes);
} // toString() method