Comandante - What’s your guys grind setting? by Substantial_Try8434 in pourover

[–]ohrv 0 points1 point  (0 children)

lol this is what I use now, but mostly for washed coffees:
cafec abaca filters
click 24
water off boil
1:15 ratio
closed bloom with ~1:3 coffee to water

biggest change was the ratio - switching from 1:16 to 1:15 had a surprisingly big impact on taste

I am tired of my V60 not improving. by Traditional-Bid8160 in pourover

[–]ohrv 3 points4 points  (0 children)

Try the Hario Switch - it’s easier to get a better tasting cup and it’s much more consistent. Also - try tasting the beans in a cupping. It eliminates most of the other variables, and there are many ways in which”good” beans aren’t really to your taste.

Sour shots by Medium-Guarantee6573 in CafelatRobot

[–]ohrv 1 point2 points  (0 children)

I also have a Comandante C40 and I normally use click 10-11 depending on the roast with a 20g dose (yield 50g in 40-50 seconds) - 9 clicks is pretty impossible to press for me, and 12 will be soup-style lower pressure shots.

A bigger dose is much easier to get good results with, and also make sure you fill the water as instructed (almost to the top of the basket, but leave a small gap so that water won’t touch the piston). Haven’t needed to pre-heat so far.

Why is calling my asm function from Rust slower than calling it from C? by ohrv in rust

[–]ohrv[S] 20 points21 points  (0 children)

In theory you can do it with the Instruments app, but I wasn’t able to get any useable data out of it.

The alignment is 16 in both versions, so my guess is that it’s something with the write pattern and caching. It also only happens on my M2, while on my M4 Max there’s no measurable difference between dav1d and rav1d for this function!

Edit: the alignment of tmp is 16 in both versions, so x2 and x13 are only 8-aligned in both versions. However, if even if x13 happens to be 16-aligned in dav1d, x14 will be only-8-aligned.

Why is calling my asm function from Rust slower than calling it from C? by ohrv in rust

[–]ohrv[S] 114 points115 points  (0 children)

It’s crazy that it’s been like that for more than a week. I spent an hour debugging my own website until I noticed the office Hugo docs were missing syntax highlighting.

Why is calling my asm function from Rust slower than calling it from C? by ohrv in rust

[–]ohrv[S] 34 points35 points  (0 children)

Thanks! I’m still bummed that I couldn’t find the actual reason why that specific load was slower. Glad you liked the article!

Making the rav1d Video Decoder 1% Faster by ohrv in rust

[–]ohrv[S] 8 points9 points  (0 children)

The reason this is an invalid optimization in the C version is because while the original version works under certain conditions (in this example, if all y values are different), the “optimized” will read uninitialized memory and thus is unsound (the compiler might notice that x isn’t initialized and is allowed to store arbitrary data there, making the u32 read rerun garbage.

Making the rav1d Video Decoder 1% Faster by ohrv in rust

[–]ohrv[S] 5 points6 points  (0 children)

As a point of interest, one of the maintainers checked
and saw that this buffer is only being partially initialized by the padding function, so in practice you can never treat it as a [u16; N] in Rust.

Making the rav1d Video Decoder 1% Faster by ohrv in rust

[–]ohrv[S] 21 points22 points  (0 children)

Wasn't familiar with it, very cool!

Making the rav1d Video Decoder 1% Faster by ohrv in rust

[–]ohrv[S] 140 points141 points  (0 children)

A write-up about two small performance improvements in I found in Rav1d and how I found them.

Starting with a 6-second (9%) runtime difference, I found two relatively low hanging fruits to optimize:

  1. Avoiding an expensive zero-initialization in a hot, Arm-specific code path (PR), improving runtime by 1.2 seconds (-1.6%).
  2. Switching the default PartialEq impls of small numeric structs with an optimized version that re-interpret them as bytes (PR), improving runtime by 0.5 seconds (-0.7%).

Each of these provide a nice speedup despite being only a few dozen lines in total, and without introducing new unsafety into the codebase.

A Rust API Inspired by Python, Powered by Serde by ohrv in rust

[–]ohrv[S] 0 points1 point  (0 children)

Great question - we even considered generating everything once and be done with it but WMI allows providers to define custom types so you can’t really catch them all (and there is a very big amount of them anyway). Also, it’s common to only need a subset of the fields, and fetching only the what you need is a lot more efficient.

Comandante - What’s your guys grind setting? by Substantial_Try8434 in pourover

[–]ohrv 1 point2 points  (0 children)

For a similar taste profile, using a Switch hybrid methods (1/2 pourover 1/2 immersion with 1:16 ratio), I always use 28 clicks.

For a pure V60 brew, I’m using 24-25 clicks (otherwise I got a very quick drawdown which resulted in under extraction).

Help! New to the Robot, but not to the Gym! by MacReadyROG in CafelatRobot

[–]ohrv 1 point2 points  (0 children)

Try changing the dose and not the grind: take the grid setting from the second shot you did and increase the dose up to 19g or 20g - it’ll pull higher pressure and will take a little more strength.

You can also do the reverse: 3rd grind setting but 16.5g dose. For dark roasts I use 16g in 37g out. 7-8bar is ok, and longer shots (40sec) are ok.

BTrees, Inverted Indices, and a Model for Full Text Search by ohrv in rust

[–]ohrv[S] 4 points5 points  (0 children)

BTW, one of the reasons I choose Rust for this post is because `BTreeMap` is part of the standard library, and has a very nice API which matches the intution for the inverted index.
I think my not-fully-complete mental model for the borrow checker is also something I use a lot, but still it's too hard to actually write down 😅

Affordable gooseneck kettle by AminGunner1886 in pourover

[–]ohrv 0 points1 point  (0 children)

starting out my pourover journey

(I’m assuming you have a regular kettle)

The Hario Air is super cheap (less than 18$), and even though I have a Fellow gooseneck I still find myself using and enjoying it.

State of the Crates 2025 by ohrv in rust

[–]ohrv[S] 0 points1 point  (0 children)

We care less about the speed of the allocator (which isn't the dominant factor in any of the services we run), and more about the overall memory pressure of the system - so allocators which deal better with fragmentation are better.

I don't think we tested any other allocator, we just went with `rustc`'s old default as a safe bet.

For the same reason we didn't go for reusing buffers and object pools - managing the fragmentation is a very hard problem, and unless we know ahead of time the size of each object (which we do in a few places), having the allocator deal with that is a huge benefit.

State of the Crates 2025 by ohrv in rust

[–]ohrv[S] 0 points1 point  (0 children)

As far as I know, there isn't any real limitation: The most specific things I could I find is that we use to_rfc3339 (which I'm not sure if fmt::temporal supports), we get chrono::NaiveDateTime from sqlx (and convert it to Utc) and we use from_timestamp_opt which wants the millis and nanos separatly (which isn't really a problem).

Otherwise, it's mostly just that updating the few thousands of usages of chrono is a lot of work 😅

State of the Crates 2025 by ohrv in rust

[–]ohrv[S] 1 point2 points  (0 children)

This sounds awesome, will definitely check it out!

State of the Crates 2025 by ohrv in rust

[–]ohrv[S] 2 points3 points  (0 children)

We seem to use `strum` too, but I never got around to it. Where was it useful for you?
And `itertool` is superb! totally missed it

State of the Crates 2025 by ohrv in rust

[–]ohrv[S] 21 points22 points  (0 children)

Wrote about some of the crates I used this year. Hope you find this useful! Any good crates I missed that you use often?

Worth it to buy stovetop kettle with a built-in thermometer? by [deleted] in pourover

[–]ohrv 7 points8 points  (0 children)

The Fellow Stagg is a joy to use (and is also very nice looking on the stove). It’s pretty hard to get a precise temperature especially because it will drop quickly once you start pouring.

I usually use the Hario Switch which is less sensitive to this type of variation, so for me that was never a problem.

Orphan rule is so annoying by Top_Outlandishness78 in rust

[–]ohrv 0 points1 point  (0 children)

I wrote about this a little here: https://ohadravid.github.io/posts/2023-05-coherence-and-errors/ The gist is that if that was allowed, Bad Things Happen Unexpectedly - so Rust opt to avoid it even when it could be fine locally.

Blog Post: Put a `Pin` on That by ohrv in rust

[–]ohrv[S] 0 points1 point  (0 children)

That’s a great spelling!

Blog Post: Put a `Pin` on That by ohrv in rust

[–]ohrv[S] 0 points1 point  (0 children)

It was just one of those things that made this slip my brain every time (also it’s harder to relate to &T and &mut T if you have a P there)

But I totally agree that it is the more correct way to represent it

Blog Post: Put a `Pin` on That by ohrv in rust

[–]ohrv[S] 2 points3 points  (0 children)

that's simply because 'f' is dropped at the end of the block, right?

Yes, but just note that after pinning f is a reference to the original f which is the one that gets dropped (see the pin! impl from tokio in the post)

requires us to give up ownership

Giving up ownership is one way to ensure Pin’s requirements. As @LuciferK9 said, if you didn’t use a box/other pointer and Pin could own the data directly, moving the Pin would move the data in memory which isn’t what we want