小编Sam*_*mee的帖子

如果在多个系统调用中完成,为什么TCP套接字会减慢?

为什么以下代码变慢?慢一点我的意思是100x-1000x慢.它只是直接在TCP套接字上重复执行读/写操作.奇怪的是,只有当我使用两个函数调用进行读取和写入时,它仍然很慢,如下所示.如果我更改服务器或客户端代码以使用单个函数调用(如在注释中),它将变得非常快.

代码段:

int main(...) {
  int sock = ...; // open TCP socket
  int i;
  char buf[100000];
  for(i=0;i<2000;++i)
  { if(amServer)
    { write(sock,buf,10);
      // read(sock,buf,20);
      read(sock,buf,10);
      read(sock,buf,10);
    }else
    { read(sock,buf,10);
      // write(sock,buf,20);
      write(sock,buf,10);
      write(sock,buf,10);
    }
  }
  close(sock);
}
Run Code Online (Sandbox Code Playgroud)

我们在一个更大的程序中偶然发现了这个,它实际上是使用stdio缓冲.当有效载荷大小超过缓冲区大小的那一刻,它神秘地变得缓慢.然后我做了一些挖掘strace,最后将问题归结为此.我可以通过愚弄缓冲策略来解决这个问题,但我真的很想知道这里到底发生了什么.在我的机器上,当我将两个读取呼叫更改为单个呼叫时,我的机器上的时间从0.030秒到超过一分钟(在本地和远程机器上测试).

这些测试是在各种Linux发行版和各种内核版本上完成的.结果相同.

具有网络样板的完全可运行的代码:

#include <netdb.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/ip.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>

static int getsockaddr(const char* name,const char* port, struct sockaddr* res)
{
    struct addrinfo* list;
    if(getaddrinfo(name,port,NULL,&list) < 0) return …
Run Code Online (Sandbox Code Playgroud)

c sockets linux performance tcp

14
推荐指数
1
解决办法
4143
查看次数

列出bash"bind -x"绑定

我搜索过man bash,但找不到列出所有当前bind -x键绑定的内容.有什么办法可以吗?我尝试了以下方法:

$ bind -x '"\C-`":"echo hello"'
# test binding: press CTRL+`
hello
# Binding works!
$ bind -p | grep 'hello'
# no output
$ bind -S
# no output
Run Code Online (Sandbox Code Playgroud)

那么,有什么方法可以看到所有bind -x当前活动的列表吗?

linux bash shell

12
推荐指数
2
解决办法
2443
查看次数

GHC评估策略

我对使用GHC 7.6.3编译后如何执行以下代码感到困惑

import qualified Data.Map as M

main = do let m1 = M.fromList $ zip [1..10000000] [1..]
          putStrLn $ "Value = " ++ (show $ M.map (+2) m1 M.! 555)
Run Code Online (Sandbox Code Playgroud)

编译ghc --make -O3,它得到以下结果:

$ /usr/bin/time ./MapLazy
Value = 557
29.88user 2.16system 0:32.12elapsed 99%CPU (0avgtext+0avgdata 2140348maxresident)k
0inputs+0outputs (0major+535227minor)pagefaults 0swaps
Run Code Online (Sandbox Code Playgroud)

然而,如果我将其更改为just show $ m1 M.! 555,我的内存使用率会降低很多,但需要几乎相同的时间:

$ /usr/bin/time ./MapLazy
555
23.82user 1.17system 0:25.06elapsed 99%CPU (0avgtext+0avgdata 1192100maxresident)k
0inputs+0outputs (0major+298165minor)pagefaults 0swaps
Run Code Online (Sandbox Code Playgroud)

这里到底发生了什么?整个Map是否因为我读出一个值而实例化?我可以以某种方式阻止它吗?我的意思是,它是一个二叉搜索树,所以我期待我在新地图上查找的一条路径实际被评估.

haskell lazy-evaluation ghc

9
推荐指数
1
解决办法
159
查看次数

将GHC中的单独项目联系起来

好的,这应该很简单,但似乎无法解决这个问题.我有两个项目,ProjectA和ProjectB.ProjectB依赖于旧项目ProjectA.现在我想构建ProjectB.我现在不想更改ProjectA的目录结构.问题是,我总是在ProjectA中使用-outputdir bin.

ProjectA看起来像这样:

ProjectA/
  bin/
    (*.o, *.hi in proper paths, sometimes also *.p_o and *.p_hi)
  Foo/
    ModuleX.hs
  ModuleA.hs
  ModuleB.hs
Run Code Online (Sandbox Code Playgroud)

现在我有一个与ProjectB不同的文件夹,它有自己独立的-outputdir.我只需要链接到旧的项目对象文件(不重新编译ProjectA文件).我意识到我可能会把ProjectA搞砸......但是没有更简单的方法吗?

haskell ghc

5
推荐指数
1
解决办法
217
查看次数

随机置换大型列表(超过1亿个元素)

我不关心以"功能"方式做到这一点.但我确实需要它在线性时间(不是O(n log n)),我真的更喜欢类型签名保持完整(即,不添加其他类型约束).这是我到目前为止,但我不断得到堆栈溢出:

import Control.Monad
import Control.Monad.ST
import Data.Array.ST
import Data.STRef
import System.Random

randomPermute :: RandomGen g => [a] -> g -> ([a],g)
randomPermute l rgen = runST $ newListArray (1,n) l >>= body rgen where
  n = length l
  body :: RandomGen g => g -> STArray s Int e -> ST s ([e],g)
  body rgen arr = do
    rgenRef <- newSTRef rgen
    let pick i j   = do vi <- readArray arr i
                        vj <- readArray arr j …
Run Code Online (Sandbox Code Playgroud)

haskell

1
推荐指数
1
解决办法
260
查看次数

标签 统计

haskell ×3

ghc ×2

linux ×2

bash ×1

c ×1

lazy-evaluation ×1

performance ×1

shell ×1

sockets ×1

tcp ×1