solana icon indicating copy to clipboard operation
solana copied to clipboard

Add a measure_block macro

Open apfitzge opened this issue 3 years ago • 2 comments

Problem

The existing measure! macro can change the way we write our code, and is not always easy to use when we want access to several variables assigned in the block being measured.

Summary of Changes

Added a new procedural macro measure_block! which inserts a measure::start and stop call around a block of code. All variables assigned inside the block are still accessible outside.

Fixes #

apfitzge avatar Aug 08 '22 00:08 apfitzge

Can you link to a place in the code base where this proc macro would be useful, esp. compared to measure!()?

Personally, I find the idea that variables escape the "scope" of the proc macro to be quite unexpected. Worst case would be grabbing some lock inside the macro invocation parens and assuming it would be dropped at the closing paren, but didn't.

I feel that maybe if there's a usage of measure!() that is clunky, then either (1) use the Measure directly, or (2) refactor the code/block. Without seeing a specific example it's hard for me to see a 'pro' that outweighs the 'con' of escaping-scope.

brooksprumo avatar Aug 08 '22 18:08 brooksprumo

Can you link to a place in the code base where this proc macro would be useful, esp. compared to measure!()?

Draft PR: #26976 (an example, but also ones where measure! is the better choice). Take a look at banking_stage.rs:612

Personally, I find the idea that variables escape the "scope" of the proc macro to be quite unexpected. Worst case would be grabbing some lock inside the macro invocation parens and assuming it would be dropped at the closing paren, but didn't.

Hadn't considered a case with a lock, I guess that could be confusing. Though if you don't want things to escape you can always just wrap it in {}.

I feel that maybe if there's a usage of measure!() that is clunky, then either (1) use the Measure directly, or (2) refactor the code/block. Without seeing a specific example it's hard for me to see a 'pro' that outweighs the 'con' of escaping-scope.

Using Measure directly is always an option, that's what the macro is doing internally. Only difference is you can't forget to stop the measure. Calling the as_us(), or similar functions on the direct Measures will just return 0 if you forget to call stop.

apfitzge avatar Aug 08 '22 22:08 apfitzge

Can you link to a place in the code base where this proc macro would be useful, esp. compared to measure!()?

Draft PR: #26976 (an example, but also ones where measure! is the better choice). Take a look at banking_stage.rs:612

Looking briefly, I think measure!() should work fine here, as it looks like the expression block example.

            let (res, measure) = measure!(
                if let ForwardOption::ForwardTpuVote = forward_option {
                    // The vote must be forwarded using only UDP.
                    banking_stage_stats
                        .forwarded_vote_count
                        .fetch_add(packet_vec_len, Ordering::Relaxed);
                    let pkts: Vec<_> = packet_vec.into_iter().zip(repeat(addr)).collect();
                    batch_send(socket, &pkts).map_err(|err| err.into())
                } else {
                    // All other transactions can be forwarded using QUIC, get_connection() will use
                    // system wide setting to pick the correct connection object.
                    banking_stage_stats
                        .forwarded_transaction_count
                        .fetch_add(packet_vec_len, Ordering::Relaxed);
                    let conn = connection_cache.get_connection(&addr);
                    conn.send_wire_transaction_batch_async(packet_vec)
                }
            );

Is this sufficient?

Edit: I skipped over that you said measure! is the better choice; sorry!

I think I'm still in the boat where without a specific example, the scope-escaping potential seems like too much of a footgun to me.

brooksprumo avatar Aug 12 '22 20:08 brooksprumo

I think I'm still in the boat where without a specific example, the scope-escaping potential seems like too much of a footgun to me.

Well that's my fault, I referenced the wrong line number somehow, I meant line 668. But yeah, I think you're probably right. This is more confusing than it's worth.

apfitzge avatar Aug 12 '22 21:08 apfitzge