solana
                                
                                
                                
                                    solana copied to clipboard
                            
                            
                            
                        Add a measure_block macro
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 #
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.
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 theMeasuredirectly, 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.
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.
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.