做完rust全链路
This commit is contained in:
1 parent
e428265357
commit
2a4b446252
34 files changed
+1756
-1031
No files matched your search
@@ -4,13 +4,16 @@ import ChuSQL.Algebra.Eval (evalRelOp)
|
||||
import ChuSQL.Algebra.Optimize (optimize)
|
||||
import ChuSQL.Algebra.Planner (translate)
|
||||
import ChuSQL.Model
|
||||
import ChuSQL.Syntax.Parser (parseQuery)
|
||||
import ChuSQL.Syntax.Parser (parseStatement)
|
||||
import Control.Exception (evaluate)
|
||||
import Data.IORef (IORef, newIORef, readIORef)
|
||||
import System.CPUTime (getCPUTime)
|
||||
import System.Environment (getArgs)
|
||||
import Text.Printf (printf)
|
||||
|
||||
-- 性能基准:同一批语句,比较优化前后的耗时。
|
||||
|
||||
-- | 造一张 users 表
|
||||
mkUsers :: Int -> Table
|
||||
mkUsers n =
|
||||
Table
|
||||
@@ -22,6 +25,7 @@ mkUsers n =
|
||||
]
|
||||
}
|
||||
|
||||
-- | 造一张 orders 表
|
||||
mkOrders :: Int -> Int -> Table
|
||||
mkOrders n m =
|
||||
Table
|
||||
@@ -33,37 +37,41 @@ mkOrders n m =
|
||||
]
|
||||
}
|
||||
|
||||
-- | 结果校验和(防被优化掉)
|
||||
checksum :: Either String [Row] -> Int
|
||||
checksum (Left _) = -1
|
||||
checksum (Right rows) = go 0 rows
|
||||
where
|
||||
-- \| 累加行长
|
||||
go acc [] = acc
|
||||
go acc (r : rs) = go (acc + length r) rs
|
||||
|
||||
-- | 结果行数
|
||||
rowCount :: Either String [Row] -> Int
|
||||
rowCount (Left _) = -1
|
||||
rowCount (Right rows) = length rows
|
||||
|
||||
-- salt 是从 IORef 里读出来的:有了这个"IO 里来的"依赖,GHC 就没法把整段纯计算
|
||||
-- 提到循环外只算一次 —— 否则批量计时会把 1 次的开销除以 k,测出 0.000 ms 这种假数据
|
||||
-- | 跑一次,返回校验和
|
||||
runOnce :: IORef String -> Database -> String -> Bool -> IO Int
|
||||
runOnce saltRef db sql useOpt = do
|
||||
salt <- readIORef saltRef
|
||||
let result = case parseQuery (sql ++ salt) >>= translate of
|
||||
let result = case parseStatement (sql ++ salt) >>= translate of
|
||||
Left e -> Left e
|
||||
Right plan -> evalRelOp db (if useOpt then optimize db plan else plan)
|
||||
forced <- evaluate (checksum result)
|
||||
return forced
|
||||
|
||||
-- | 跑一次,返回行数
|
||||
resultRows :: IORef String -> Database -> String -> Bool -> IO Int
|
||||
resultRows saltRef db sql useOpt = do
|
||||
salt <- readIORef saltRef
|
||||
let result = case parseQuery (sql ++ salt) >>= translate of
|
||||
let result = case parseStatement (sql ++ salt) >>= translate of
|
||||
Left e -> Left e
|
||||
Right plan -> evalRelOp db (if useOpt then optimize db plan else plan)
|
||||
_ <- evaluate (checksum result)
|
||||
return (rowCount result)
|
||||
|
||||
-- | 量一段 IO 的 CPU 时间
|
||||
timed :: IO a -> IO Double
|
||||
timed act = do
|
||||
t0 <- getCPUTime
|
||||
@@ -71,13 +79,16 @@ timed act = do
|
||||
t1 <- getCPUTime
|
||||
return (fromIntegral (t1 - t0) / 1e12)
|
||||
|
||||
-- | 加倍批量次数再折算单次
|
||||
benchOp :: Double -> IO Int -> IO (Double, Int)
|
||||
benchOp target act = loop 1
|
||||
where
|
||||
-- \| 批次翻倍直到超过目标
|
||||
loop k = do
|
||||
t <- timed (mapM_ (const act) [1 .. k])
|
||||
if t < target then loop (k * 2) else return (t / fromIntegral k, k)
|
||||
|
||||
-- | 打印一个用例的对比
|
||||
report :: IORef String -> Database -> Double -> String -> IO ()
|
||||
report saltRef db target sql = do
|
||||
nUn <- resultRows saltRef db sql False
|
||||
@@ -107,6 +118,7 @@ queries =
|
||||
warmupSql :: String
|
||||
warmupSql = "SELECT name FROM users"
|
||||
|
||||
-- | 基准入口
|
||||
main :: IO ()
|
||||
main = do
|
||||
args <- getArgs
|
||||
|
||||
Reference in new issue
Block a user