簡體   English   中英

使用Nix,如何在啟用性能分析的情況下指定Haskell依賴項?

[英]With Nix, how can I specify Haskell dependencies with profiling enabled?

我最初是這樣嘗試的:

nix-shell -p "haskell.packages.ghc821.ghcWithPackages (p: with p; [text hspec lens])" -j4 --run 'ghc Main.hs -prof

然后GHC告訴我

Main.hs:4:1: error:
    Could not find module ‘Control.Lens’
    Perhaps you haven't installed the profiling libraries for package ‘lens-4.15.4’?
    Use -v to see a list of the files searched for.

在網上搜索我發現了這個: https//github.com/NixOS/nixpkgs/issues/22340

所以我似乎無法從緩存中下載。 但是沒關系,如果至少我可以在本地構建配置文件變體。

我可以通過簡單地修改給予-p的nix表達式來實現嗎?

然后在寫這個問題的這一點上,我記得這個資源: https//github.com/NixOS/nixpkgs/blob/bd6ba7/pkgs/development/haskell-modules/lib.nix

我在哪里找到了enableLibraryProfiling 所以我嘗試過:

nix-shell -p "haskell.packages.ghc821.ghcWithPackages (p: with p; [text hspec (haskell.lib.enableLibraryProfiling lens)])" -j4 --run 'ghc Main.hs -prof'

這讓我遇到了一個新錯誤:

src/Control/Lens/Internal/Getter.hs:26:1: error:
    Could not find module ‘Data.Functor.Contravariant’
    Perhaps you haven't installed the profiling libraries for package ‘contravariant-1.4’?
    Use -v to see a list of the files searched for.
   |
26 | import Data.Functor.Contravariant
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

因此,如果我可以將所有包映射到enableLibraryProfiling上,那么我想這可行。 但是我的nix知識目前並沒有完全擴展到那么遠。 我怎么能這樣做? 這甚至是正確的追求途徑嗎?

通過進一步窺探nix-repl和來自ElvishJerricco的一些有用的指針來自FreeNode的#reflex-frp,我能夠構建這個,這似乎有效:

$ nix-shell -p "(haskell.packages.ghc821.extend (self: super: {mkDerivation = expr: super.mkDerivation (expr // { enableLibraryProfiling = true; });})).ghcWithPackages (p: with p; [text hspec lens])" -j4 --run 'ghc Main.hs -prof'

我想出了一個簡單的方法,我正在使用Nix進行關於Haskell開發的最大博客文章。 現在,這里只是分析部分的文本:

尼克斯相當容易。 首先,我們將以下內容添加到~/.config/nixpkgs/config.nix

{
  packageOverrides = super: let self = super.pkgs; in
  {
    profiledHaskellPackages = self.haskellPackages.override {
      overrides = self: super: {
        mkDerivation = args: super.mkDerivation (args // {
          enableLibraryProfiling = true;
        });
      };
    };
  };
}

現在在我們想要profiling-shell.nix的項目中,我們創建了一個新的profiling-shell.nix

let nixpkgs = import <nixpkgs> {};
    orig = nixpkgs.pkgs.profiledHaskellPackages.callPackage ./default.nix {};
in (nixpkgs.pkgs.haskell.lib.doBenchmark orig).env

除了使用我們剛剛全局定義的profiledHaskellPackages之外,幾乎與我們的普通shell.nix相同。 現在,調用nix-shell profiling-shell.nix將重建項目中的每個依賴項,並啟用分析。 第一次這樣做需要很長時間。 幸運的是,這並沒有破壞我們的Nix商店 - 一個vanilla nix-shell似乎確實再次呈現我們的常規依賴,沒有重新下載或重建。

警告: nix-collect-garbage -d將從我們的Nix Store中刪除所有自定義庫,如果需要,我們必須再次構建它們。

如果我們正在編寫一個庫,那么我們可以分析的最接近的可執行文件將是我們的基准套件。 要做到這一點:

  • -prof-fprof-auto添加到我們的基准GHC選項中
  • 重新生成default.nix
  • 輸入我們的分析shell: nix-shell profiling-shell.nix
  • cabal configure --enable-library-profiling --enable-benchmarks
  • cabal build
  • dist/build/projname/projname-bench +RTS -p
  • 查看生成的projname-bench.prof文件

根據結果​​,我們可以在正常的Nix Shell中進行代碼更改,刪除分析選項,重新生成default.nix和基准。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM