nix icon indicating copy to clipboard operation
nix copied to clipboard

Cache evaluation for eval and flake check

Open balsoft opened this issue 4 years ago • 5 comments

Is your feature request related to a problem? Please describe.

Running nix flake check multiple times without changing the repository can take way too long. For flakes describing multiple NixOS systems all of which depend on programs built with IFD-heavy haskell.nix, nix flake check can take 10s of seconds.

Describe the solution you'd like

It would be very useful if nix eval and nix flake check used evaluation caching.

balsoft avatar Nov 24 '20 13:11 balsoft

I marked this as stale due to inactivity. → More info

stale[bot] avatar Jun 02 '21 16:06 stale[bot]

Still an issue

ncfavier avatar Jun 20 '21 23:06 ncfavier

I have some WIP to fix this on https://github.com/NixOS/nix/tree/eval-cache . It’s still a WIP because the performance isn’t on par with the current cache. But if someone wants to have a second look at it to see what could be made faster, that could help a lot

thufschmitt avatar Jun 21 '21 06:06 thufschmitt

I marked this as stale due to inactivity. → More info

stale[bot] avatar Jan 03 '22 20:01 stale[bot]

still an issue

tomberek avatar Jan 23 '22 06:01 tomberek

In divnix/std-action we run one mass evaluation up front and then share those results using the github action cache to a myriad of task runners built from a specialized json. Since the process of calling this evauation also reifies any referenced derivations to disk, we can then call any task runners or builder jobs directly on the drv files themselves.

The idea is to allow the runners to avoid the cost of running Nix evaluations at all and instead allow them to get to work immediately. If the eval cache was popullated from nix eval it would only make our process that much more efficient; saving time right where it counts as the discovery evaluation is the bottleneck for all the rest of the work.

nrdxp avatar Dec 09 '22 01:12 nrdxp

@thufschmitt is there something wrong with something along these lines? It seems that eval does populate the cache, but does not use it. Other code paths like nix build know the type of what is requested, thus use the appropriate getter, but eval does not.

link: https://github.com/NixOS/nix/compare/master...flox:nix:eval_eval_cache

diff --git a/src/libexpr/eval-cache.cc b/src/libexpr/eval-cache.cc
index afe575fee..fe0ba3211 100644
--- a/src/libexpr/eval-cache.cc
+++ b/src/libexpr/eval-cache.cc
@@ -382,6 +382,30 @@ AttrKey AttrCursor::getKey()
 
 Value & AttrCursor::getValue()
 {
+    if (root->db) {
+        if (!cachedValue)
+            cachedValue = root->db->getAttr(getKey());
+        if (cachedValue && !std::get_if<placeholder_t>(&cachedValue->second)) {
+            if (auto s = std::get_if<string_t>(&cachedValue->second)) {
+                debug("using cached string attribute '%s'", getAttrPathStr());
+                auto v = root->state.allocValue();
+                v->mkString(s->first);
+                return *v;
+            }
+            else if (auto s = std::get_if<bool>(&cachedValue->second)) {
+                debug("using cached bool attribute '%s'", getAttrPathStr());
+                auto v = root->state.allocValue();
+                v->mkBool(*s);
+                return *v;
+            }
+            else if (auto s = std::get_if<int_t>(&cachedValue->second)) {
+                debug("using cached int attribute '%s'", getAttrPathStr());
+                auto v = root->state.allocValue();
+                v->mkInt(s->x);
+                return *v;
+            }
+        }
+    }
     if (!_value) {
         if (parent) {
             auto & vParent = parent->first->getValue();

Perhaps the performance cost on many misses?

tomberek avatar Jan 08 '23 16:01 tomberek

Briefly discussed in the Nix team meeting

  • @roberth: Remember we don't yet store evaluation errors in the eval cache. For these commands where showing errors / not excluding failures is the point, we should be wary of using the Eval cache until it is improved.

  • @edolstra: Yeah will look into that too.

Assigned to @edolstra

Ericson2314 avatar Aug 18 '23 12:08 Ericson2314

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2023-08-18-nix-team-meeting-minutes-80/32081/1

nixos-discourse avatar Aug 23 '23 07:08 nixos-discourse