Aeson库提供两种json解析器:严格的和懒惰的。懒惰的人声称可以节省时间但是创造了thunk,而严格的人节省了空间并且花费了更多的时间(如果数据不经常访问的话)。我有以下玩具程序来查看它们之间的区别,但配置文件是相同的:
import Data.Aeson
import Data.ByteString as B
import Data.Attoparsec.ByteString as P
import System.Environment
main = do
[fn] <- getArgs
fc <- B.readFile fn
let r = P.parse json' fc
case r
of Done _ _ -> print ":)"
_ -> print ":("
当程序完全访问数据时,两个解析器也具有相同的性能:
...
case r
of Done _ j -> print j
_ -> print ":("
为什么懒人版本不会在第一个程序中节省时间而在第二个程序中浪费空间?有一个示例,其中一个解析器明显获胜?
更新:以下是我最近使用FromJSON
进行的实验,该实验也无法区分decode
与decode'
Data Weirder = Weirder
instance FromJSON Weirder where
parseJSON (Number n) = return $! undefined -- $! trace "weirdercalled" Weirder -- `seq` Weirder
main = do
[fn] <- getArgs
fc <- B.readFile fn
let Just rs = decode fc :: Maybe [Weirder]
print $ length rs
我已尝试打印head
,last
,翻转刘海并插入seq
,但都是一样的......