做完rust全链路

This commit is contained in:
LIm1tZz7 committed 2026-09-24 21:28:49 +08:00
1 parent e428265357
commit 2a4b446252
34 files changed
+1756 -1031

No files matched your search

+17 -5
View File
@@ -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