Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.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 - Fatal编程技术网

java套接字速度异常低

java套接字速度异常低,java,Java,我只是从这个论坛复制了一个数据传输的例子,并在我的程序中使用了它,但我看不出它的速度有什么问题。我测试了主要示例,它在不到30毫秒的时间内传输了大约1MB的数据。读写速度都很好。但当我在我的案例中使用它时,相同数量的数据不会在不到400毫秒的时间内传输!写作仍然有效,但阅读却有问题 在这里,数据被写入。现在,我不想加速第一部分,即对象的序列化。我的问题是关于第二部分 private static void writeObject(OutputStream out, Object obj) thr

我只是从这个论坛复制了一个数据传输的例子,并在我的程序中使用了它,但我看不出它的速度有什么问题。我测试了主要示例,它在不到30毫秒的时间内传输了大约1MB的数据。读写速度都很好。但当我在我的案例中使用它时,相同数量的数据不会在不到400毫秒的时间内传输!写作仍然有效,但阅读却有问题

在这里,数据被写入。现在,我不想加速第一部分,即对象的序列化。我的问题是关于第二部分

private static void writeObject(OutputStream out, Object obj) throws IOException {
    long t1 = System.currentTimeMillis();

    ByteArrayOutputStream bArr = new ByteArrayOutputStream();
    ObjectOutputStream ojs = new ObjectOutputStream(bArr);
    ojs.writeObject(obj);
    ojs.close();

    long t2 = System.currentTimeMillis();

    byte[] arr = bArr.toByteArray();
    int len = arr.length;
    for (int i = 0; i < arr.length; i += BUFFER_SIZE)
        out.write(arr, i, Math.min(len - i, BUFFER_SIZE));
    out.close();

    long t3 = System.currentTimeMillis();

    System.out.println(t3 - t2);
}
下面是
main()

我哪里出错了

(关于的强制性评论)

看起来您正在启动两个线程,一个读线程和一个写线程。按照以下顺序进行是完全可行的:

  • 读卡器线程启动
  • 读卡器线程记录
    t1
  • 读卡器线程调用
    read()
    ,但由于没有可用数据而被阻止
  • 写入线程开始
  • 写入线程睡眠一秒钟
  • writer线程调用
    write()
  • 写入线程退出
  • 读取器线程的
    read()
    调用返回
  • 读卡器线程
    t2
    等,然后退出

  • 现在,如果您看到
    t2-t1
    有大约400ms的时间,这可能不是正在发生的事情:写入线程对
    sleep()
    的调用似乎很可能是在录制
    t1
    之前发生的。但简单的回答是,似乎不清楚
    t2-t1
    在测量什么。特别是,期望它仅测量执行工作所需的时间(而不是等待数据读取)似乎是不正确的。

    如果您想使用缓冲IO进行读取和写入,可以分别使用和进行读取和写入。而且,你可以使用一个按钮来关闭。写,比如

    private static final int BUFFER_SIZE = 32 * 1024;
    private static void writeObject(OutputStream out, Object obj) //
                throws IOException {
        try (ObjectOutputStream ojs = new ObjectOutputStream(//
                    new BufferedOutputStream(out, BUFFER_SIZE));
            ojs.writeObject(obj);
        }
    }
    
    读起来像

    private static Object readObject(InputStream in) throws IOException,//
                ClassNotFoundException {
        try (ObjectInputStream ois = new ObjectInputStream(//
                    new BufferedInputStream(in, BUFFER_SIZE))) {
            return ois.readObject();
        }
    }
    

    当您执行微基准测试时,我建议您至少在CPU时间的前2秒忽略所有结果,以便给JVM一个预热的机会

    我会写这篇文章而不用睡觉

    为了测试的目的,编写对象是不相关的。您只需编写一个
    新字节[size]
    并查看需要多长时间

    为了测试短延迟,我将使用
    System.nanoTime()

    我会先写一条短信,看看往返时间。i、 客户端向服务器发送一个数据包,服务器再次将其发送回来

    最后但并非最不重要的一点是,通过使用Java1.4(2004)中添加的NIO,您将获得更好的性能

    下面是一些前面编写的代码,它会产生如下结果

    On a E5-2650 v2 over loopback
    Throughput was 2880.4 MB/s
    Loop back echo latency was 5.8/6.2 9.6/19.4 23.2us for 50/90 99/99.9 99.99%tile
    
    注意:这些时间是将数据包发送到服务器并再次发送的完整往返时间。计时单位为微秒

    我刚刚复制了一个工作示例

    不,你没有。你编了一些完全不同的东西

        int len = arr.length;
        for (int i = 0; i < arr.length; i += BUFFER_SIZE)
            out.write(arr, i, Math.min(len - i, BUFFER_SIZE));
    
    然而,这一切只会增加延迟和浪费空间。
    私有静态void writeObject(OutputStream out,Object obj)抛出IOException{ long t1=System.currentTimeMillis(); out.writeObject(obj); out.close(); long t2=System.currentTimeMillis()

    ByteArrayOutputStream
    中没有任何意义,向真实的
    ObjectOutputStream
    中写入的字节数超过其中的字节数是完全无效的。基准测试操作中没有任何意义,永远不应该发生


    为什么要关闭
    ObjectOutputStream
    是另一个谜。可能在接收端也有类似的代码:使用
    ObjectInputStream.readObject()重新复制所有内容。

    为什么要将内容压缩到
    字节[]
    s?@ElliottFrisch我还能怎么做缓冲?你确定数字吗?1GB的30毫秒传输速度为267 Gbit/s(无开销)!哦,对不起,是1MB!我刚刚编辑了我的帖子。但是问题显然没有解决!!你是对的!但问题仍然存在!!正如你在我编写的代码中看到的,由于
    线程的睡眠()
    。我刚刚把它扩展到了2秒,而且它变得更好了。现在它的写入时间不到10毫秒,但读取时间超过100毫秒。正如我所提到的,主要示例在这两方面都用的时间要少得多。此外,我想在服务器/客户端程序中使用该技术,客户端发送一些数据,然后等待回答。如果一秒钟不够,因此,当它等待服务器响应时,问题就更大了。我猜
    sleep()
    将用作临时同步机制,以便在写入线程的
    Socket()之前调用读取器线程的
    accept()
    。我想知道如果你在读线程调用
    accept()
    readObject()
    之间再加一次睡眠,你会得到什么值,这样写线程(大概)在开始阅读之前就完成了写。是的!这改变了故事!但是当我把
    sleep()放在
    正如您所建议的,读取时间减少到10毫秒以下,但是当我删除
    sleep()时,写入时间却增加到100毫秒以上
    这些数字被交换了!!为什么?!@user1389026我怀疑睡眠并没有真正影响这些方法的性能。除了线程何时被调度这一显而易见的秘密之外,
    read()
    write()
    是从缓冲区获取或写入缓冲区的方法。它们可能需要等待缓冲区准备好进行操作,而不需要进行实际的数据传输工作。Elliott,
    BufferedXXXXStream
    的默认缓冲区大小是多少?。好的,您对测试的看法是正确的。但问题在于实际情况!
    On a E5-2650 v2 over loopback
    Throughput was 2880.4 MB/s
    Loop back echo latency was 5.8/6.2 9.6/19.4 23.2us for 50/90 99/99.9 99.99%tile
    
        int len = arr.length;
        for (int i = 0; i < arr.length; i += BUFFER_SIZE)
            out.write(arr, i, Math.min(len - i, BUFFER_SIZE));
    
    out.write(arr, 0, len);
    
        System.out.println(t2-t1);
    }