Newest at the top
2024-11-14 17:03:44 +0100 | <geekosaur> | gc only gets involved when the pointer reaches the end of the nursery |
2024-11-14 17:03:31 +0100 | <geekosaur> | the nursery/gen 0 is a bump-pointer allocator |
2024-11-14 17:03:20 +0100 | <geekosaur> | not magic |
2024-11-14 17:03:13 +0100 | <bailsman> | I agree - I'm not really sure. Some GC magic probably. But the point is that it's builtin and optimized, so it's much faster than trying to emulate in-place updates, which compiles to a morass of work and not 5 asm instructions like the c version. |
2024-11-14 17:02:06 +0100 | <geekosaur> | because it's probably not what actually happens |
2024-11-14 17:01:56 +0100 | <geekosaur> | bailsman, what do you think is going on during an allocation? |
2024-11-14 17:01:22 +0100 | <EvanR> | yes it is |
2024-11-14 17:01:08 +0100 | <bailsman> | No it isn't. |
2024-11-14 17:00:57 +0100 | <EvanR> | allocating nodes in haskell is much faster |
2024-11-14 17:00:38 +0100 | <EvanR> | are you allocating nodes with malloc |
2024-11-14 17:00:31 +0100 | <EvanR> | that's... not going to be an apples to apples comparison |
2024-11-14 17:00:30 +0100 | <bailsman> | So I think I'm concluding that map is "the best you can do in haskell" because it's optimized and a builtin, and any attempt to do in place algorithms is just going to be massively slow. |
2024-11-14 17:00:06 +0100 | <bailsman> | To test my theory, I wrote a C version of the benchmark. Updating a linked list by allocating nodes one by one and copying over the values takes 14ms, approximately as long as Haskell takes to do map. Updating 1M records inplace in an array takes 2ms. |
2024-11-14 16:59:12 +0100 | <geekosaur> | and the tree example is probably closer to your actual AST than a list zipper example would be |
2024-11-14 16:58:51 +0100 | <geekosaur> | even if it won't work with your structure as is, the wiki page I pointed you to earlier describes what you can do with a zipper |
2024-11-14 16:58:42 +0100 | lortabac | (~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4) (Quit: WeeChat 4.4.2) |
2024-11-14 16:57:58 +0100 | <geekosaur> | you can do anything to the focused node including remove or replace it, and moving the zipper will reknit the tree |
2024-11-14 16:57:30 +0100 | <ph88> | ok cool, thanks geekosaur ! |
2024-11-14 16:57:24 +0100 | <geekosaur> | that'd be a zipper |
2024-11-14 16:57:24 +0100 | <ph88> | can zipper do this too ? |
2024-11-14 16:56:59 +0100 | <ph88> | what if i don't only want to change the variable `a` but i also want to inspect the nodes and modify/replace them ? |
2024-11-14 16:56:55 +0100 | <geekosaur> | if you just want something Traversable-style, any generics library will give you that |
2024-11-14 16:56:38 +0100 | <geekosaur> | which it sounded like you wanted |
2024-11-14 16:56:27 +0100 | <geekosaur> | although the default traversals are all of the Traversable variety, unlike a zipper which lets you move at will |
2024-11-14 16:56:11 +0100 | <ph88> | and you still recommend to do the traversal with zipper yes? (with code derived with generics) |
2024-11-14 16:55:35 +0100 | <geekosaur> | then use generics to derive the traversal (all of the generics packages do so in some fashion) |
2024-11-14 16:55:26 +0100 | <ph88> | as i understood it can be ghc.generics with zipper, or lens or maybe something else |
2024-11-14 16:55:03 +0100 | <ph88> | i have neither, and i like something to traverse while not having to write traversal code for each type |
2024-11-14 16:54:45 +0100 | <ph88> | why would i want this? "it's easier to replace lens there with something else (such as a zipper)" |
2024-11-14 16:54:18 +0100 | <geekosaur> | that's why generics packages exist |
2024-11-14 16:54:05 +0100 | <geekosaur> | if, as you say, "that's going to take so much time, the AST is absolutely huge", you need generics of some variety to escape that |
2024-11-14 16:53:17 +0100 | <geekosaur> | ph88, it's easier to replace lens there with something else (such as a zipper) than it is to replace the generics mechanism needed to make lens/a zipper/whatever useful |
2024-11-14 16:48:08 +0100 | <EvanR> | and looking at the core, of your own code |
2024-11-14 16:47:46 +0100 | <EvanR> | again, "I don't know how this benchmark library works, but I'll assume a bunch of conclusions" isn't as good as writing your own code then profiling |
2024-11-14 16:46:58 +0100 | <geekosaur> | you're conflating things, syb/generics/uniplate are mechanism, lens uses the mechanism. and lens should indeed be able to navigate up/down |
2024-11-14 16:46:55 +0100 | <EvanR> | so you won't see that benefit there |
2024-11-14 16:46:45 +0100 | <bailsman> | I only do one operation. |
2024-11-14 16:46:34 +0100 | <EvanR> | bailsman, Vector shines when you start with combine chains of operations together, it fuses away intermediate vectors |
2024-11-14 16:46:30 +0100 | tromp | (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
2024-11-14 16:45:50 +0100 | <ph88> | geekosaur, do you think it's still worth to use zippers but then to combine them with a generic approach? i am not sure whether i can go up and down with other approaches such as lens or GHC.Generics |
2024-11-14 16:44:49 +0100 | <EvanR> | 4x faster isn't that much of a difference, it seems plausible you're creating the whole structure for everything. It's not like a 1000x speedup that you'd normally see when you switch from full evaluation to lazy evaluation |
2024-11-14 16:44:43 +0100 | <geekosaur> | that's where generics or syb come in, they generate the necessary code for you |
2024-11-14 16:44:34 +0100 | <ph88> | that's going to take so much time, the AST is absolutely huge |
2024-11-14 16:44:17 +0100 | misterfish | (~misterfis@31-161-39-137.biz.kpn.net) (Ping timeout: 248 seconds) |
2024-11-14 16:44:14 +0100 | <geekosaur> | exactly, yes |
2024-11-14 16:44:05 +0100 | <ph88> | geekosaur, doable .. would i have to write code for each data type? |
2024-11-14 16:43:53 +0100 | <bailsman> | Anyway, I guess we can assume that it isn't cheating, it is actually constructing the intermediate list, and most of the performance difference is going to come from map being a builtin and the vector code not compiling to anything nearly as simple as what I expected. So it's not map being fast, it's map being slowish, and vector being slower, I think. |
2024-11-14 16:43:39 +0100 | <geekosaur> | especially when you have multiple data types |
2024-11-14 16:43:32 +0100 | <EvanR> | control what ultimately is demanding evaluation |
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 |