Newest at the top
2024-11-14 16:43:17 +0100 | <EvanR> | when I was tooling with the profiling and performance I would make sure to write my own main IO action so I know what what's |
2024-11-14 16:42:26 +0100 | <geekosaur> | ph88, it's doable without any of those but it's harder since you have to write it all yourself. those libraries exist for a reason |
2024-11-14 16:42:16 +0100 | <EvanR> | in the case of list |
2024-11-14 16:42:07 +0100 | <EvanR> | if nf works, computes full normal form, sounds bad for performance |
2024-11-14 16:41:39 +0100 | <EvanR> | I'm not familiar with Benchmarkable |
2024-11-14 16:41:23 +0100 | <bailsman> | nf :: NFData b => (a -> b) -> a -> Benchmarkable |
2024-11-14 16:41:16 +0100 | <EvanR> | finalList <- evaluate (force (map updateValue someList)) ought to slow it down more |
2024-11-14 16:40:20 +0100 | <EvanR> | right now all I see is "map updateValue someList" |
2024-11-14 16:40:04 +0100 | <EvanR> | I have no idea, I don't see what nf is or bench is |
2024-11-14 16:39:52 +0100 | <bailsman> | That's what the nf was for right? |
2024-11-14 16:39:46 +0100 | <bailsman> | Isn't that what I'm doing already? |
2024-11-14 16:39:37 +0100 | <EvanR> | fully evaluated the final list before doing whatever it does with it |
2024-11-14 16:39:24 +0100 | <EvanR> | go to the benchmark code and cripple that |
2024-11-14 16:39:07 +0100 | <bailsman> | How do I prevent it from doing that? |
2024-11-14 16:38:58 +0100 | <EvanR> | and again, the benchmark code might have gotten optimized so there are no list nodes, other than the source list |
2024-11-14 16:38:45 +0100 | <bailsman> | I'm expecting the vector version to compile to something like `nv = new Vector(v.length); for (int i = 0; i < v.length; ++i) nv[i] = updateValue(v[i])`. One allocation, extremely simple update. Whereas the linked list version has to allocate 1M nodes and set up each of their 'next' pointers, so it seems like it should be doing more work. |
2024-11-14 16:38:01 +0100 | philopsos | (~caecilius@user/philopsos) philopsos |
2024-11-14 16:37:56 +0100 | <haskellbridge> | <flip101> Bowuigi: could you please take a look as well? |
2024-11-14 16:37:04 +0100 | <EvanR> | it goes back to how your "bench" thing is processing the final list, 1 by 1, it's nicer on the GC |
2024-11-14 16:36:40 +0100 | <EvanR> | and 1 megabyte chunk of Vector might not play as nice with the GC |
2024-11-14 16:35:55 +0100 | <bailsman> | but there's only 1 of them, not 1 million |
2024-11-14 16:35:46 +0100 | <EvanR> | it's larger than 1 list node |
2024-11-14 16:35:31 +0100 | <bailsman> | Why is the vector larger? |
2024-11-14 16:35:20 +0100 | <EvanR> | you may or may not be allocating any list nodes due to fusion, but even if you did, that's 1 node per item. Meanwhile the IntMap has a more complex structure and the Vector is larger, even if you ignore the fact that you have to copy it |
2024-11-14 16:35:07 +0100 | <ph88> | geekosaur, i went back and forth with chatgpt for a bit. Could you take a peek at this document, specifically on line 490 https://bpa.st/MSVA it made an example with tree zippers to implement something for each type, which i don't want. Is there a way to use tree zippers without resorting to generic programming solutions such as GHC.Generics, syb, lens or Data.Data ? |
2024-11-14 16:34:44 +0100 | <bailsman> | My intuitions are completely wrong, but I don't know exactly why. |
2024-11-14 16:33:58 +0100 | <bailsman> | It should be harder because you need to allocate and create a linked list |
2024-11-14 16:33:57 +0100 | <EvanR> | even simpler if the source list already exists and doesn't need to be evaluated |
2024-11-14 16:33:49 +0100 | <bailsman> | Why is it simpler? It's the same operation |
2024-11-14 16:33:36 +0100 | <EvanR> | well, mapping a list to get another list is much simpler than building a big tree or copying a vector so you can mutate it |
2024-11-14 16:32:33 +0100 | <bailsman> | I'd like to understand exactly what's going on to make map so much faster. |
2024-11-14 16:32:27 +0100 | <EvanR> | code doesn't do anything in isolation, the evaluation is on demand |
2024-11-14 16:32:01 +0100 | <EvanR> | well that will have a big effect on performance |
2024-11-14 16:31:36 +0100 | alexherbo2 | (~alexherbo@2a02-8440-3313-668b-a9ec-921f-0511-ee3f.rev.sfr.net) alexherbo2 |
2024-11-14 16:31:16 +0100 | alexherbo2 | (~alexherbo@2a02-8440-3313-668b-a9ec-921f-0511-ee3f.rev.sfr.net) (Remote host closed the connection) |
2024-11-14 16:29:48 +0100 | Inst | (~Inst@user/Inst) Inst |
2024-11-14 16:29:46 +0100 | <bailsman> | I don't understand either but it printed some numbers to my console output |
2024-11-14 16:29:37 +0100 | <bailsman> | I copied that from some example code to do a benchmark somewhere |
2024-11-14 16:29:31 +0100 | <EvanR> | or `nf' ? |
2024-11-14 16:29:18 +0100 | kuribas` | (~user@ip-188-118-57-242.reverse.destiny.be) (Remote host closed the connection) |
2024-11-14 16:28:44 +0100 | Inst_ | (~Inst@user/Inst) (Ping timeout: 272 seconds) |
2024-11-14 16:28:39 +0100 | <EvanR> | it's not clear what defaultMain and bench do |
2024-11-14 16:26:49 +0100 | <EvanR> | trying to +1 everything in the collection? |
2024-11-14 16:26:42 +0100 | <bailsman> | All are using the same updateValue function. |
2024-11-14 16:26:13 +0100 | <bailsman> | please point out any beginner mistakes there |
2024-11-14 16:26:07 +0100 | <bailsman> | EvanR: I posted the source code of my benchmark here. https://paste.tomsmeding.com/B6koT8Nx |
2024-11-14 16:25:39 +0100 | <lambdabot> | Unknown command, try @list |
2024-11-14 16:25:39 +0100 | <EvanR> | @SmallRecord is a type, updateValue_r2HH should be another thing defined in the dump somewhere |
2024-11-14 16:25:24 +0100 | <bailsman> | sorry list function, I guess they're all pure except the mutable vector one |
2024-11-14 16:25:05 +0100 | <bailsman> | The pure function just translates to: updatePure_r2HI = map @SmallRecord @SmallRecord updateValue_r2HH |