我正在寻找一种能够存储任何DAG的数据结构,但是能够有效地(即,在边/顶点的数量中进行次线性)检测是否添加边缘会创建一个循环(从而防止您破坏非循环不变量) ).有谁知道这样的事情?
谢谢!
我正在使用Data.Serialize.Get
并且正在尝试定义以下组合器:
getConsumed :: Get a -> Get (ByteString, a)
Run Code Online (Sandbox Code Playgroud)
它应该像传入的Get
动作一样,但也返回消耗的ByteString
那个Get
.用例是我有一个二进制结构,我需要解析和散列,并且在解析它之前我不知道它的长度.
这个组合器尽管语义简单,但实现起来却非常棘手.
没有深入研究内部Get
,我的直觉是使用这种怪异:
getConsumed :: Get a -> Get (B.ByteString, a)
getConsumed g = do
(len, r) <- lookAhead $ do
before <- remaining
res <- g
after <- remaining
return (before - after, res)
bs <- getBytes len
return (bs, r)
Run Code Online (Sandbox Code Playgroud)
哪个将使用前瞻,查看运行操作之前和之后的剩余字节,返回操作的结果,然后消耗长度.这不应该复制任何工作,但偶尔会失败:
*** Exception: GetException "Failed reading: getBytes: negative length requested\nEmpty call stack\n"
Run Code Online (Sandbox Code Playgroud)
所以我一定是在某个地方误解谷物.
有没有人看到我的定义getconsumed
有什么问题,或者对如何实现它有更好的想法?
编辑:Dan Doel指出,remaining …
我听到很多关于JVM JIT 可以做什么,但是没有看到很多关于如何分析JIT在程序的给定运行中实际执行的操作的信息.有许多关于使用的提示-XX:+PrintCompilation
,-XX:+PrintOptoAssembly
但它会导致很难解释的真正低级别的信息.
一般来说,在优化期间,我喜欢使用具有专用JIT预热时间的基本通用操作套件等等,但我希望能够看到哪些优化实际上触发了我的代码.也许我的JVM考虑内联一个特定的方法调用,但它的一些东西使它决定不,或者JIT无法避免我的循环中的数组边界检查,因为我的措辞我的不变量和循环条件太模糊.我希望像YourKit这样的工具能够支持某种形式的"JIT正在发生的事情",但我无法在YourKit或其他任何地方找到支持.
理想情况下,我只是喜欢JIT优化器在我的程序运行期间所想的大脑转储.假设我已经充分预热了我的功能,它决定将三个方法内联到我的内循环中并将循环分成三个部分,中间部分没有数组边界检查,我想要总结这些决定和动机对他们来说
我错过了一些明显的东西吗?JVM性能感知程序员在优化紧密内循环以找出正在发生的事情时会做些什么?当然,低级别的-XX
旗帜不是唯一的选择,可以吗?我很欣赏有关如何最好地处理JVM上的这种低级内容的提示.不,这个问题不是过早优化的动机!:)
编辑:我想我想要的一些东西是由给出的,-XX:+LogCompilation
但我仍然很好奇,如果人们有这种活动的一般提示和工具.
我希望看到源的非确定性交错操作,类型签名如
interleave :: WhateverIOMonadClassItWouldWant m => [(k, Source m a)] -> Source m (k, a)
Run Code Online (Sandbox Code Playgroud)
用例是我有一个p2p应用程序,它保持与网络上许多节点的开放连接,而且它主要是坐在等待来自其中任何节点的消息.当消息到达时,它不关心它来自何处,但需要尽快处理消息.理论上,这种应用程序(至少用于类似套接字的源)可以完全绕过GHC的IO管理器并运行select
/ epoll
/ etc.直接打电话,但我并不特别在意它是如何实现的,只要它有效.
管道可以这样吗?一种不那么通用但可能更可行的方法可能是编写一个[(k, Socket)] -> Source m (k, ByteString)
处理所有套接字接收的函数.
我注意到ResumableSource
管道中的操作,但它们似乎都想要了解一个特定的Sink
,这感觉就像一个抽象泄漏,至少对于这个操作.