Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #307 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 6 6
Lines 666 664 -2
=========================================
- Hits 666 664 -2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Oooh, nice. I have a feeling that's one of those obvious-in-hindsight changes. :D I'll have a closer look. |
b2e1175 to
73c6e4b
Compare
|
Technically, this is a breaking change. If anyone has been saving a reference to the Raw func of type func(string) Node, their code will break. In practice, I'm not sure anyone would do that. I think the Group change predates 1.0, but I'd have to check. |
|
How about this then? It preserves the advantages while being fully backwards-compatible, as far as I can see. Edit: Okay, small correction, it does not preserve all the advantages, because now we cannot use |
Although I can't think of a use case for when the breaking change would be a problem (someone keeping a But I think it's still a nice change, even though the And now you can do basically the same change for Text/Textf, right? |
|
I can merge this after just some tiny fixes. :-) |
Yeah, if you want to preserve full compatibility, I fully understand. Something for a potential v2.
Yes, this version still preserves all other advantages, and still is a big improvement.
Yes, this is what I was talking about above, but it depended on how you wanted to handle this issue, and you indeed brought up the backwards-compatibility issue I did not consider. |
|
Sorry, I mis-clicked. I did not mean to close the PR. |
https://github.com/Hendrikto/gomponents/tree/optimize-text Should I include this in this PR, or open another one? |
Yes, although I'm hoping I will never have to make a v2. :D
Nice! I'd prefer a separate PR. |
|
There must be one line somewhere that's not covered by tests. :D |
|
It’s the String method, which is not used, as |
Haha, of course. Could you add a small test for it? I'm oddly proud of the 100% coverage. 😅 |
|
I think option 1 makes more sense, so that is what I implemented for now. |
|
Great, thanks! Sorry for my late reply, I've been on an Easter break and haven't been near my computer much. I think we're ready to merge this? |
Before: ``` ❯ go test . -bench=BenchmarkRaw -benchmem goos: linux goarch: amd64 pkg: maragu.dev/gomponents cpu: AMD Ryzen 9 9950X3D 16-Core Processor BenchmarkRaw/raw_element-32 42365084 29.47 ns/op 48 B/op 2 allocs/op BenchmarkRawf/formatted_raw_element-32 15052114 76.10 ns/op 112 B/op 4 allocs/op PASS ok maragu.dev/gomponents 2.397s ❯ ll -B build/release .rwxr----- 11,823,144 hendrik 25 Mar 15:23 -I build/release ``` After: ``` ❯ go test . -bench=BenchmarkRaw -benchmem goos: linux goarch: amd64 pkg: maragu.dev/gomponents cpu: AMD Ryzen 9 9950X3D 16-Core Processor BenchmarkRaw/raw_element-32 74832258 17.55 ns/op 24 B/op 1 allocs/op BenchmarkRawf/formatted_raw_element-32 20046828 60.94 ns/op 64 B/op 3 allocs/op PASS ok maragu.dev/gomponents 2.538s ❯ ll -B build/release .rwxr----- 11,758,312 hendrik 25 Mar 15:23 -I build/release ```
I figured as much, no worries :)
If you do not have any objections, I think this is ready, yes. |
|
@Hendrikto merged! Thank you again for your work. :-) Want to tackle |
Yeah, I already had the branch ready for some time, but it depended on this being merged first, so that is why I did not send it before, but I did now.
Thanks for making gomponents 😄 |
By making use of the new `raw` type, we can also simplify and optimize
`Text[f]`, similar to the `Raw[f]` optimizations[0].
Before:
```
❯ go test . -bench=Text -benchmem
goos: linux
goarch: amd64
pkg: maragu.dev/gomponents
cpu: AMD Ryzen 9 9950X3D 16-Core Processor
BenchmarkText/simple_text_element-32 32014112 41.18 ns/op 40 B/op 2 allocs/op
BenchmarkTextf/formatted_text_element-32 13197096 92.03 ns/op 112 B/op 4 allocs/op
PASS
ok maragu.dev/gomponents 2.536s
```
After:
```
❯ go test . -bench=Text -benchmem
goos: linux
goarch: amd64
pkg: maragu.dev/gomponents
cpu: AMD Ryzen 9 9950X3D 16-Core Processor
BenchmarkText/simple_text_element-32 32165613 39.41 ns/op 32 B/op 2 allocs/op
BenchmarkTextf/formatted_text_element-32 15473426 77.65 ns/op 64 B/op 3 allocs/op
PASS
ok maragu.dev/gomponents 2.472s
```
[0]: #307
Hi @markuswustenberg,
This is (part of) the optimizations I mentioned in #296, which can now be properly benchmarked, with those fixes.
By making
g.Rawa type, we get significantly improved performance, combined with lower memory usage:Before:
After:
Moreover, we also significantly decrease binary size. On a production app, with this single change, I get:
And that is with only 58 occurences of
g.Raw, which amounts to about 1118 bytes saved perg.Rawinstance! Unfortunately, the project is proprietary, so I cannot share the code here, but you should be able to easily verify this.All tests still pass, and nothing changes from a library consumer perspective. This is similar to Make
Groupa type #202, whereg.Groupwas made a type.This change also reduces code duplication, conceptually, syntactically, and semantically simplifies the design a lot, making the code easier to read, and helping the compiler.
It also affords us new possibilities, like writing functions that take parameters of type
g.Raw, or definingg.Rawconstants.Overall, I think this design is just superior in every way. I was unable to identify any drawbacks, and I only see big advantages.
If you agree with this change, I have further similar improvements, but I wanted to gauge your interest first.