我在haskell中实现了一个服务器进程,它充当一个简单的内存数据库.客户端进程可以连接然后添加和检索数据.该服务使用的内存比我预期的多,而且我试图解决原因.
我最粗略的指标是linux"top".当我开始这个过程时,我看到"VIRT"图像大小约为27MB.在运行客户端以插入60,000个数据项后,我看到图像大小为~124MB.
我最初看到运行流程来捕获GC统计数据(+ RTS -S)
Alloc Copied Live GC GC TOT TOT Page Flts
bytes bytes bytes user elap user elap
28296 8388 9172 0.00 0.00 0.00 0.32 0 0 (Gen: 1)
Run Code Online (Sandbox Code Playgroud)
并且在添加60k项目时,我看到实时字节平滑增长
...
532940 14964 63672180 0.00 0.00 23.50 31.95 0 0 (Gen: 0)
532316 7704 63668672 0.00 0.00 23.50 31.95 0 0 (Gen: 0)
530512 9648 63677028 0.00 0.00 23.50 31.95 0 0 (Gen: 0)
531936 10796 63686488 0.00 0.00 23.51 31.96 0 0 (Gen: 0)
423260 10047016 …Run Code Online (Sandbox Code Playgroud) 我对attoparsec的这种行为感到有点困惑.
$ ghci
> :m Data.Attoparsec.Text
> :m + Data.Text
> parse (string (pack "module")) (pack "mox")
Partial _
> parse (string (pack "module")) (pack "moxxxx")
Fail "moxxxx" [] "Failed reading: takeWith"
>
Run Code Online (Sandbox Code Playgroud)
为什么我需要添加字符才能触发失败?
一旦遇到第一个"x",它不应该失败吗?
我一直在尝试使用类型系列来抽象UI工具包.当我尝试使用HLists(http://homepages.cwi.nl/~ralf/HList/)改进API时,我已经失败了.
我的API最初看起来像这样:
{-# LANGUAGE TypeFamilies #-}
class UITK tk where
data UI tk :: * -> *
stringEntry :: (UITK tk) => UI tk String
intEntry :: (UITK tk) => UI tk Int
tuple2UI :: (UI tk a,UI tk b) -> (UI tk (a,b))
tuple3UI :: (UI tk a,UI tk b,UI tk c) -> (UI tk (a,b,c))
tuple4UI :: (UI tk a,UI tk b,UI tk c,UI tk d) -> (UI tk (a,b,c,d))
ui :: (UITK tk) => (UI tk (String,Int)) …Run Code Online (Sandbox Code Playgroud) Tkinter顶级窗口似乎有两种"模式":大小由应用程序决定,用户控制大小.考虑以下代码:
from tkinter import *
class Test(Frame):
def __init__(self,parent):
Frame.__init__(self,parent)
self.b1 = Button(self, text="Button 1",command=self.b1Press)
self.b1.pack()
def b1Press(self):
print("b1Press")
label = Label(self, text="Label")
label.pack()
root = Tk()
ui = Test(root)
ui.pack(fill='both', expand=1)
root.mainloop()
Run Code Online (Sandbox Code Playgroud)
每次按下按钮,可见窗口都会改变大小以适应其他标签.但是,如果我手动调整窗口大小(使用鼠标),则会停止此自动调整大小的行为,从那时起,我必须手动更改窗口的大小以查看添加时的新按钮.
是什么决定了顶层窗口的大小是否受应用程序或用户的控制?
用户手动调整大小后,应用程序如何重新获得自动调整大小?
我有一些代码具有与此相同的结构:
import Debug.Trace
newtype SomeExpensiveHiddenType = SCHT Double
expensive :: Double -> Double -> SomeExpensiveHiddenType
expensive a b = SCHT $ trace "call expensive" (*) a b
cheap :: SomeExpensiveHiddenType -> Double -> Double
cheap (SCHT x) c = trace "call cheap" (+) x c
f1 :: Double -> Double -> Double -> Double
f1 a b c = let x = expensive a b in cheap x c
Run Code Online (Sandbox Code Playgroud)
ie f1是一个函数,它根据前两个参数计算昂贵的结果,然后将其与第三个参数一起使用.我原本希望对前两个参数进行部分应用,然后重复应用第三个参数会导致昂贵的计算只运行一次.不幸的是,这种情况并非如此:
test1 = do
putStrLn "test 1"
let p …Run Code Online (Sandbox Code Playgroud)