为什么将函数移动到模块时运行时间会增加?

Tru*_*arg 5 optimization performance profiling haskell massiv

我不明白出了什么问题。我使用 stack new 创建了模板项目,添加一些代码:

module Main where

import Lib
import           Data.Massiv.Array           (Sz (..), Vector)

import qualified Data.Massiv.Array           as A
import Data.Time.Clock.POSIX

t mul = round . (mul *) <$> getPOSIXTime
timeMillis = t 1000

area :: BBox -> Double
area (BBox (x1, y1) (x2, y2)) = (x2 - x1) * (y2 - y1)

sumOfAreas :: Vector A.DS BBox -> Double
sumOfAreas bboxes = A.sfoldl (\acc box -> acc + area box) 0 bboxes

main :: IO ()
main = do
    start <- timeMillis
    putStrLn $ "Start " ++ show start
    let
        bboxes = A.makeArray A.Seq (Sz 10000 * 10000) $ (\_ -> BBox (0, 0) (12, 12)) :: Vector A.DS BBox
        result = sumOfAreas bboxes
    putStrLn $ show result
    end <- timeMillis
    putStrLn $ show (end - start)
Run Code Online (Sandbox Code Playgroud)
module Lib where

import           Data.Massiv.Array           (Vector)

import qualified Data.Massiv.Array           as A

type Point = (Double, Double)

data BBox =
  BBox (Point) (Point)
  deriving (Eq, Show)
Run Code Online (Sandbox Code Playgroud)

在我的硬件上,这平均需要 100 毫秒。

接下来,我决定移动Lib模块中的功能。更新:

module Main where

import Lib
import           Data.Massiv.Array           (Sz (..), Vector)

import qualified Data.Massiv.Array           as A
import Data.Time.Clock.POSIX

t mul = round . (mul *) <$> getPOSIXTime
timeMillis = t 1000

main :: IO ()
main = do
    start <- timeMillis
    putStrLn $ "Start " ++ show start
    let
        bboxes = A.makeArray A.Seq (Sz 10000 * 10000) $ (\_ -> BBox (0, 0) (12, 12)) :: Vector A.DS BBox
        result = sumOfAreas bboxes
    putStrLn $ show result
    end <- timeMillis
    putStrLn $ show (end - start)
Run Code Online (Sandbox Code Playgroud)
module Lib where

import           Data.Massiv.Array           (Vector)

import qualified Data.Massiv.Array           as A

type Point = (Double, Double)

data BBox =
  BBox (Point) (Point)
  deriving (Eq, Show)

area :: BBox -> Double
area (BBox (x1, y1) (x2, y2)) = (x2 - x1) * (y2 - y1)

sumOfAreas :: Vector A.DS BBox -> Double
sumOfAreas bboxes = A.sfoldl (\acc box -> acc + area box) 0 bboxes
Run Code Online (Sandbox Code Playgroud)

现在运行时间约为 1000 毫秒。

cabal 文件看起来像:

cabal-version: 1.12

-- This file has been generated from package.yaml by hpack version 0.35.0.
--
-- see: https://github.com/sol/hpack
-- ... info ...

source-repository head
  type: git
  location: https://github.com/githubuser/profiling

library
  exposed-modules:
      Lib
  other-modules:
      Paths_profiling
  hs-source-dirs:
      src
  ghc-options: -Wall -threaded -O3
  build-depends:
      base >=4.7 && <5
    , massiv ==1.0.1.1
    , vector ==0.12.3.1
    , array ==0.5.4.0
    , time ==1.9.3
  default-language: Haskell2010

executable profiling-exe
  main-is: Main.hs
  other-modules:
      Paths_profiling
  hs-source-dirs:
      app
  ghc-options: -Wall -threaded -O3
  build-depends:
      base >=4.7 && <5
    , massiv ==1.0.1.1
    , vector ==0.12.3.1
    , array ==0.5.4.0
    , time ==1.9.3
    , profiling
  default-language: Haskell2010

test-suite profiling-test
  type: exitcode-stdio-1.0
  main-is: Spec.hs
  other-modules:
      Paths_profiling
  hs-source-dirs:
      test
  ghc-options: -Wall -threaded -O3
  build-depends:
      base >=4.7 && <5
    , profiling
  default-language: Haskell2010
Run Code Online (Sandbox Code Playgroud)

堆栈版本

Version 2.9.1, Git revision 409d56031b4240221d656db09b2ba476fe6bb5b1 x86_64 hpack-0.35.0
Run Code Online (Sandbox Code Playgroud)

ghc 版本 9.2.4。

事实上,当我在主模块本身的游乐场项目之一中导出一个函数时,我遇到了这种行为。

如何解释这种情况以及如何避免这种情况?我缺少什么?