Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这个Java算法如何更快_Java_Algorithm_Binary_Linked List_Ascii - Fatal编程技术网

这个Java算法如何更快

这个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&

我有一个循环,它将布尔链接列表拆分8位,并返回缓冲区中每个字节的ASCII值。函数返回字符串缓冲区

如果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