pathom

2023-07-31T22:28:04.361249Z

i'm having an issue where my resolver (very simple, just a map of 1 key to a map of 100s of keys) is taking 100-200ms to access. this is cached, without cache it takes 3s to access. i feel like a map lookup shouldn't take so long. the value being returned is very large, but i'm only accessing a key in it and the rest i don't use.

(let [pathom-lookup  (util/time "pathom-lookup" (generated-templates ::resource))
        clojure-lookup (util/time "clojure-lookup" (pathom-lookup :resource/project-equity-edit-page))])

"Elapsed time: 132.809939 msecs for: pathom-lookup"
"Elapsed time: 0.001092 msecs for: clojure-lookup"
this seems very weird. my cache is an atom. when i do lookups on an atom with the same data as pathom-lookup they take 0.03 msec i think i'm using pathom wrong, but i'm not sure how.

wilkerlucio 2023-08-01T14:12:39.995369Z

hello @pppaul, yes, looking at the data, its a lot of keys, and Pathom does have overhead to merge (a simple merge in pathom has a lot of checks it needs to do, like if has something nested to process, check for plugins running, etc...)

wilkerlucio 2023-08-01T14:12:55.111799Z

so if your real data is gonna look like that, Pathom overhead will be significant

2023-08-01T17:00:40.366929Z

if i turn each key into it's own resolver, will that fix things? cus otherwise i might as well build my own interface over a graph

wilkerlucio 2023-08-01T17:02:08.939889Z

depends on how you load/merge, if you load in smaller pieces, yes, Pathom will be able to only fetch the nescessary parts for a given process, and avoid a lof the overhead in this case

2023-08-01T17:03:33.200879Z

i don't need pathom to know about most of this data, maybe i could do something indirect.

wilkerlucio 2023-08-01T18:05:00.081149Z

actually, I just did some profiling, and I found out most of the time is being spent at the map-select-ast (which is the part of the process that cleans up keys that were not requested)

wilkerlucio 2023-08-01T18:05:07.231369Z

results after removing that part:

(let [pathom-lookup  (labeled-time "pathom-lookup" (run-eql ::resource))
        clojure-lookup (labeled-time "clojure-lookup" (pathom-lookup :resource/project-equity-edit-page))])
"Elapsed time: 0.466875 msecs for: pathom-lookup"
"Elapsed time: 0.00175 msecs for: clojure-lookup"

wilkerlucio 2023-08-01T18:05:28.743489Z

I think something might be wrong there, because in this case there is no specific request for a nested thing, it should short circuit

wilkerlucio 2023-08-01T18:05:32.376269Z

I'll investigate that

wilkerlucio 2023-08-01T18:08:29.578439Z

humm, looking at the code, I remember now, Pathom will enforce the manual re-merge of everything so its sure to apply the plugin to merge ast data for every entry

wilkerlucio 2023-08-01T18:08:50.825709Z

I think we can optimize that, if the user doesn't have any plugin installed to merge-ast, we can short circuit this step

wilkerlucio 2023-08-01T18:11:18.661369Z

just to help clear this up, without any changes to Pathom, if your query is more specific and only requests a part of the ::request data, you already get a better result:

wilkerlucio 2023-08-01T18:11:27.291679Z

(let [pathom-lookup  (labeled-time "pathom-lookup" (run-eql {::resource [:resource/files-manager-cashflow]})) ; !!! note the change here
        clojure-lookup (labeled-time "clojure-lookup" (pathom-lookup :resource/project-equity-edit-page))])
"Elapsed time: 13.872583 msecs for: pathom-lookup"
"Elapsed time: 0.001041 msecs for: clojure-lookup"

wilkerlucio 2023-08-01T18:12:34.653489Z

this is because now every other key is being ignored during the map-select process, so it only has to traverse the :resource/files-manager-cashflow part

2023-08-01T22:03:43.558079Z

that is what I expected. hope that you are able to implement the optimization soon. I want to have more specific queries, but I just need more time getting used to pathom, and maybe pathom isn't good for this use case. I'll attempt this implementation again soon, but right now I converted the code to just use a clojure map

wilkerlucio 2023-07-31T22:44:21.792389Z

hello, do you think you can make a repro so I can see in all detail what is going on? are you making any plugins?

2023-07-31T22:45:01.525349Z

i'm not making plugins, i have only made the most basic resolver that i could think of just to deal with some caching, and get my feet wet with pathom

2023-07-31T22:46:16.957129Z

i need to figure out how to write this data to a file that you can use

2023-07-31T22:50:19.579779Z

my data is 21 megs, is that ok?

2023-07-31T22:58:05.952619Z

i'm setting up a repo, i'll invite you to it (don't really want it to be public)

2023-07-31T23:06:25.223239Z

i made it public, since your email isn't on slack

2023-07-31T23:08:00.883759Z

the repo exhibits the same performance problems that i get in my app codebase

nivekuil 2023-07-31T23:33:33.822069Z

it's not a map lookup you're timing it's read-string and slurp. also try with the planner cache too

2023-08-01T00:53:14.041899Z

it's not that @kevin842 as i said in my app code, that slurp is replaced with code that takes 3-4 seconds to run

2023-08-01T00:54:12.499129Z

also, i'm using cache. i don't understand what you are suggesting

2023-08-01T00:54:41.530009Z

i'm very new to pathom, this is my first use of it. i'm not able to easily understand the terminology you use

2023-08-01T00:56:02.824859Z

i created this code via reading all the related docs for the pathom functions in the code. i'm not sure what to do as i feel like i've exhausted the docs

2023-08-01T00:58:16.115459Z

@kevin842 i'm not sure where a planner cache would go, but i'm only calling 1 key in my current setup, what planning is going on?

2023-08-01T00:58:35.468289Z

not just calling 1 key, there is 1 key total

nivekuil 2023-08-01T00:58:37.249049Z

https://pathom3.wsscode.com/docs/cache/ have you read the first section there

2023-08-01T00:59:49.815079Z

ok, maybe i skipped this because i thought there was nothing to plan

2023-08-01T00:59:52.102969Z

i'll try this

2023-08-01T01:01:27.521569Z

i tried with plan cache, there is no difference

2023-08-01T01:03:12.473809Z

(pco/defresolver ^:private resource-resolver []
  {::pco/cache-store ::my-cache*}
  {::resource (init {})})
you are telling me that when i setup this resolver, with a cache, that int runs each time i interact with it?

2023-08-01T01:04:11.064949Z

i put some output on the init

"Elapsed time: 1029.986377 msecs for: init"
"Elapsed time: 1182.23776 msecs for: pathom-lookup"
"Elapsed time: 9.62E-4 msecs for: clojure-lookup"
"Elapsed time: 147.967815 msecs for: pathom-lookup"
"Elapsed time: 0.001102 msecs for: clojure-lookup"
it only runs once, when i call the resolver 2 times

2023-08-01T01:04:15.952549Z

init take 1 second

2023-08-01T01:04:27.534569Z

i don't think this is my problem

nivekuil 2023-08-01T01:18:57.869579Z

I thought init would take most of those 3 seconds, not sure where the other 2 might be coming from. If the planner isn't taking any time I guess the overhead comes from the extra steps pathom has to do, like merge the resolver output into the result accumulator and that just takes 150ms to merge a huge (20mb?) map. You can plug in a profiler like tufte to check but if that's the case I doubt there's much to optimize

nivekuil 2023-08-01T01:20:51.434779Z

the resolver cache caches a single revolver's output, not an eql query so there is going to be overhead still as pathom has to process each of them to run things like plugins

2023-08-01T01:57:28.212459Z

no, init takes 1 sec in the debug repo. in my real app it takes longer. the lookup takes 100ms. the 100ms is the problem I need solved. I can't use pathom if this is how long it takes to do a query that is on a resolver with no real logic happening

2023-08-01T01:59:05.661009Z

I'm not sure why the resolver is doing any work. derefing an atom is less than 1 ms.

nivekuil 2023-08-01T02:03:13.222929Z

the resolver isn't doing any work, the runner is. It starts with an empty map and merges resolver outputs, cached or not, into it and returns that map. That could be the cost you're seeing