gpt4 book ai didi

optimization - 创建一个大集合 - 需要减少在 GC 上花费的时间

转载 作者:行者123 更新时间:2023-12-03 16:26:34 25 4
gpt4 key购买 nike

这个程序创建了一个非常大的集合来查找哈希函数冲突。有没有办法减少 GC 花费的时间? +RTS -s 报告 GC 花费了 40% 以上的时间。

示例用法:

./program 0 1000000 +RTS -s
./program 145168473 10200000 +RTS -s

我可以使用更好的算法或数据结构吗?

{-# LANGUAGE OverloadedStrings #-}

import System.Environment
import Control.Monad
import Crypto.Hash.SHA256

import qualified Data.ByteString.Char8 as B
import qualified Data.ByteString.Lazy.Char8 as BL
import Data.Char
import Data.Int
import Data.Bits
import Data.Binary
import Data.Set as Set
import Data.List
import Numeric

str2int :: (Integral a) => B.ByteString -> a
str2int bs = B.foldl (\a w -> (a * 256)+(fromIntegral $ ord w)) 0 bs

t50 :: Int64 -> Int64
t50 i = let h = hash $ B.concat $ BL.toChunks $ encode i
in
(str2int $ B.drop 25 h) .&. 0x3ffffffffffff

sha256 :: Int64 -> B.ByteString
sha256 i = hash $ B.concat $ BL.toChunks $ encode i

-- firstCollision :: Ord b => (a -> b) -> [a] -> Maybe a
firstCollision f xs = go f Set.empty xs
where
-- go :: Ord b => (a -> b) -> Set b -> [a] -> Maybe a
go _ _ [] = Nothing
go f s (x:xs) = let y = f x
in
if y `Set.member` s
then Just x
else go f (Set.insert y s) xs

showHex2 i
| i < 16 = "0" ++ (showHex i "")
| otherwise = showHex i ""

prettyPrint :: B.ByteString -> String
prettyPrint = concat . (Data.List.map showHex2) . (Data.List.map ord) . B.unpack


showhash inp =
let h = sha256 inp
x = B.concat $ BL.toChunks $ encode inp
in do putStrLn $ " - input: " ++ (prettyPrint x) ++ " -- " ++ (show inp)
putStrLn $ " - hash: " ++ (prettyPrint h)

main = do
args <- getArgs
let a = (read $ args !! 0) :: Int64
b = (read $ args !! 1) :: Int64
c = firstCollision t [a..(a+b)]
t = t50
case c of
Nothing -> putStrLn "No collision found"
Just x -> do let h = t x
putStrLn $ "Found collision at " ++ (show x)
showhash x
let first = find (\x -> (t x) == h) [a..(a+b)]
in case first of
Nothing -> putStrLn "oops -- failed to find hash"
Just x0 -> do putStrLn $ "first instance at " ++ (show x0)
showhash x0

最佳答案

正如您所注意到的,GC 统计报告的生产率很低:

  44,184,375,988 bytes allocated in the heap
1,244,120,552 bytes copied during GC
39,315,612 bytes maximum residency (42 sample(s))
545,688 bytes maximum slop
109 MB total memory in use (0 MB lost due to fragmentation)

Tot time (elapsed) Avg pause Max pause
Gen 0 81400 colls, 0 par 2.47s 2.40s 0.0000s 0.0003s
Gen 1 42 colls, 0 par 1.06s 1.08s 0.0258s 0.1203s

INIT time 0.00s ( 0.00s elapsed)
MUT time 4.58s ( 4.63s elapsed)
GC time 3.53s ( 3.48s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 8.11s ( 8.11s elapsed)

%GC time 43.5% (42.9% elapsed)

Alloc rate 9,651,194,755 bytes per MUT second

Productivity 56.5% of total user, 56.4% of total elapsed

最明显的第一步是增加 GC 默认区域以尝试消除调整大小的需要。一招,例如is to increase the -A area (您可以使用工具like GC tune为您的程序找到正确的设置)。

  $ ./A ... +RTS -s -A200M

Total time 7.89s ( 7.87s elapsed)

%GC time 26.1% (26.5% elapsed)

Alloc rate 7,581,233,460 bytes per MUT second

Productivity 73.9% of total user, 74.1% of total elapsed

因此我们缩短了四分之一秒,但将生产率提高到了 75%。现在我们应该看看堆配置文件:

enter image description here

它显示了集合及其 Int 值的线性增长。不过,这是您的算法指定的内容,所以我看不出您能做多少事情,只要您保留所有结果。

关于optimization - 创建一个大集合 - 需要减少在 GC 上花费的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10730357/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com