2024-10-26 00:16:17 You might look at some other experiments as a starting point. My tests on a 6502 STC forth show it's about 10-20x slower than handwritten assembly. 16-bit cells on an 8-bit architecture adds to the slowdown. OTOH, mecrisp is only 2-3x slower than C since it generates optimized machine code. Your results may fall between those two. 2024-10-26 01:06:51 veltas: threaded Forth is still typically going to lose 90% of your performance 2024-10-26 01:07:21 but I agree that performance can tempt you into limiting what you can do by using the wrong tool 2024-10-26 01:12:12 or compare forth to an olden BASIC (not a fancy one that compiles to asm) 2024-10-26 01:12:42 threaded Forth is generally going to be a lot faster than a BASIC interpreter 2024-10-26 01:25:25 yep. 2-3x faster than BASIC was the claim back then 2024-10-26 02:35:34 I don't know why more people don't do native code Forths 2024-10-26 02:35:57 I wrote one - it really isn't that hard 2024-10-26 02:36:09 the trick is to inline, inline, inline 2024-10-26 02:36:17 it makes for big code, but it speeds things up 2024-10-26 02:39:30 anyone know what happened to forth-standard.org? 2024-10-26 02:57:57 no, what happened? 2024-10-26 03:09:26 it's not up 2024-10-26 03:16:24 that's a shame 2024-10-26 09:09:02 remexre: Their official website is up http://www.forth200x.org/forth200x.html 2024-10-26 09:09:33 Well their previous official website 2024-10-26 09:09:40 The official website is down I guess 2024-10-26 09:10:54 But I've always treated that one I linked as official because it actually has their meeting minutes, decisions, draft standards etc 2024-10-26 09:10:54 even today 2024-10-26 09:11:33 I don't know what the point of Forth200x is 2024-10-26 09:17:47 veltas: Unicode maybe 2024-10-26 09:20:15 I wonder how many forths have implemented that word set 2024-10-26 09:20:27 I've not looked at it in great detail, not sure if it's any good 2024-10-26 09:20:38 not sure 2024-10-26 09:21:02 the test suite seems pretty great 2024-10-26 09:21:19 That predates Forth200x I think 2024-10-26 09:21:47 Also you don't need special handling for UTF-8 for many jobs 2024-10-26 09:22:16 Although the main character I've cared about is £ so I've not been pushing quantum limits or anything lol 2024-10-26 09:22:41 it's not in dpANS 2024-10-26 09:23:02 dpans will handle £ though because UTF-8 is designed well 2024-10-26 09:23:25 But don't expect it to understand that it's one glyph in two bytes 2024-10-26 09:23:44 Mind you, neither will the unicode word set, it knows about codepoints 2024-10-26 09:23:49 I mostly care about ♥, ☺, ñ, á, é, í, ó, ú, ü, “, ”, —, –, and Greek 2024-10-26 09:24:14 2.2 × 10⁻⁶ Ω = 2.2 μΩ 2024-10-26 09:24:24 Yeah dpans 'works' for that 2024-10-26 09:24:48 mostly yeah 2024-10-26 09:24:58 the test suite isn't in dpANS is what I meant 2024-10-26 09:25:04 Creative tricks let you avoid ever really having to address this problem properly, assuming you've got a UTF-8 terminal/printer 2024-10-26 09:25:24 The test suite was an independent thing that got adopted by Forth200x 2024-10-26 09:25:32 up to a point, yeah 2024-10-26 09:25:46 Yeah 2024-10-26 09:25:59 ∫x²dx 2024-10-26 09:26:16 I would say that 'unicode anxiety' is the same as 'stack anxiety' :P 2024-10-26 09:26:33 I have a JS game engine where I often use attributes named Δx and Δy 2024-10-26 09:26:47 Don't be anxious, UTF-8 rocks 2024-10-26 09:27:13 You can use unicode in your word names in Forth too 2024-10-26 09:27:35 yeah, I think I have 2024-10-26 09:27:35 It's not guaranteed by the standard but it's completely trivial to support it and most Forths do 2024-10-26 09:28:03 it's a little bit of a pain in hold 2024-10-26 09:28:29 but most of the time you don't have single characters, it's true 2024-10-26 09:29:19 Actually I'm not 100% sure whether dpans allows it or not implicitly, it doesn't seem to be too strict 2024-10-26 09:31:23 I think from a Forth philosophy perspective, the worst thing you can do is treat programmers like they don't understand UTF-8 2024-10-26 09:31:23 Therefore does it matter that CHAR only works with the low codepoints? No, not in the slightest. 2024-10-26 09:31:35 .R is using only low codepoints 2024-10-26 09:31:38 Assuming BASE isn't mental 2024-10-26 09:31:47 yes, .r itself doesn't care 2024-10-26 09:32:07 but if you're using .r it's because you care how many spaces are being printed before your number 2024-10-26 09:32:20 Yes but the programmer *knows*, even if Forth doesn't 2024-10-26 09:32:36 e.g. if I write ." £" then I don't need to *tell* Forth it's one column, I know it is 2024-10-26 09:32:50 and the case where that's useful is when the characters on the previous and following lines are of the same width as some predictable number of spaces 2024-10-26 09:32:54 If you find yourself writing generic library to calculate number of columns then you misstepped 2024-10-26 13:48:28 Very clean C code 2024-10-26 13:51:42 oh, thanks 2024-10-26 13:53:09 it's not deliberately obscure like the JS, but I think there are parts that could be clearer 2024-10-26 14:12:17 tabemann: That's what I'm doing at moment, inlining 2024-10-26 14:16:03 Works super well for certain words, like 1+ `inc rax`, NIP `add rbx, 8`, etc; but yeah I inline longer stuff too 2024-10-26 14:19:28 Next thing I'd try would be constant folding, e.g. `1 2 LSHIFT OR` -> `or rax, 4` 2024-10-26 14:19:44 Looking for easy wins 2024-10-26 14:19:50 In Forth and in general :S 2024-10-26 15:08:19 Sounds fun and forgive me for spoiling it, but what are the harder to solve problems you've encountered? 2024-10-26 15:22:32 Everything except those 2024-10-26 15:55:42 it's a funny thing to try to take some cues from forth and apply them to c 2024-10-26 15:55:57 it makes me a little irritated at c 2024-10-26 15:58:34 zelgomer: Which cues? 2024-10-26 16:00:43 well, mainly taking factoring to the extreme. the problem is that thanks to the static typing, there's not as much reuse even though it seems like there could be 2024-10-26 16:03:45 i understand why it's like this, but even before, i always always annoyed at how strict c was with function signatures. like you can't give an int (*)(foo *, bar *) as a callback where an int (*)(foo *, void *) is expected, even though the first thing you're going to do is cast that void * to a bar *. so you end up having to create these pointless trampoline functions just to satisfy the type system. 2024-10-26 16:14:37 inlining can help some. you could also do some peepholing. ive thought about starting with combos of 3 primitives, simulating their effects then trying to generate more efficient code. you could go on to 4 and 5 primitive combos if you have room to store them and spare cycles to do the optimizing 2024-10-26 16:26:51 This reminds me of a paper where they looked at the most common Forth instruction sequences 2024-10-26 16:27:53 "The Common Case in Forth Programs" https://www.complang.tuwien.ac.at/anton/euroforth/ef01/gregg01.pdf 2024-10-26 16:29:15 Interesting table on page 7 "Figure 6: Dynamically frequent sequences of instructions for large benchmarks" 2024-10-26 17:03:28 Peephole optimisation is already much more complicated, although there's some low-hanging fruit there 2024-10-26 17:06:26 Chuck did a thing that somebody called pinhole optimization in ColorForth, I think 2024-10-26 17:07:04 I've always just leaned toward having "in my hip pocket" so to speak the ability to hand optimize with assembly where it's actually needed to boost performance. What that puts the emphasis on for me is a robust profiling system. 2024-10-26 17:07:04 E.g. + was an immediate word which would look at the last thing compiled and if it was a literal value, that would be decompiled and turned into add eax, 2024-10-26 17:07:25 Otherwise it would just compile a normal add top two items instruction 2024-10-26 17:08:17 Optimization is certainly INTERESTING, but in most applications only a very small part of your code winds up being the real time consumer. 2024-10-26 17:12:50 there is a risk of wasting a lot of time on microbenchmarks 2024-10-26 17:20:12 GeDaMo: I remember the pinhole optimizations from colorforth 2024-10-26 17:22:17 I explored using them in RetroForth's older x86 implementations, but ended up not finding them worthwhile for my (comparing the gains offered vs increased implementation complexity) 2024-10-26 17:23:00 For performance improvements, I mostly just drop to assembly for the few cases where I care 2024-10-26 17:35:24 ^^ 2024-10-26 18:11:26 veltas: applying the peephole optimizations is easy but generating ideal code for those primitives is tough. if you can do that in an automated way, you 2024-10-26 18:11:48 're part of the way to generating optimized machine code anyway 2024-10-26 18:48:07 Yeah agreed 2024-10-26 20:49:50 back 2024-10-26 20:50:55 GeDaMo: I implemented that for zeptoforth 2024-10-26 20:51:11 for a number of common primitives, I would save the last literal compiled, and if there was one, it would compile them into tighter code (preferably single instructions, but if that was not possible loading literals directly into registers rather than pushing them onto the stack) than if the literals had simply been pushed onto the stack 2024-10-26 23:18:22 zelgomer: depending on the C compiler you may be able to just cast the function pointer