为什么以下代码变慢?慢一点我的意思是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) 我搜索过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
当前活动的列表吗?
我对使用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是否因为我读出一个值而实例化?我可以以某种方式阻止它吗?我的意思是,它是一个二叉搜索树,所以我期待我在新地图上查找的一条路径实际被评估.
好的,这应该很简单,但似乎无法解决这个问题.我有两个项目,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搞砸......但是没有更简单的方法吗?
我不关心以"功能"方式做到这一点.但我确实需要它在线性时间(不是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)