Does the number of arguments matter?

Consider this function which takes in a dozen or so inputs parameters (craft) to build the header of a packet:

fn create_packet_with_cfg<T: AsRef<[u8]>>(payload: &T, cfg: &BaseHeaderConfig, pid: f64, wid: f64) -> OutboundItem {
    let payload = payload.as_ref();

    let header = ProcessedPacketHeader::craft(cfg.cid_original,
                                              cfg.cid_needed_to_undrill,
                                              cfg.drill_version_needed_to_undrill,
                                              cfg.security_level_drilled,
                                              cfg.timestamp,
                                              cfg.current_packet_hop_state,
                                              cfg.next_hop_state,
                                              cfg.endpoint_destination_type,
                                              cfg.command_flag,
                                              cfg.expects_response,
                                              cfg.oid_eid,
                                              wid.to_bits(),
                                              pid.to_bits(),
                                              cfg.route_dest_nid,
                                              cfg.route_dest_cid,
                                              cfg.network_map_version);
    let mut packet = Vec::with_capacity(PACKET_HEADER_BYTE_COUNT + payload.len());
    header.inscribe_into(&mut packet);
    packet.extend(payload);
    packet
}

I have heard that this is undesirable... should a builder pattern be used? I would think that using a builder that returns an &mut Self continuously is not the way to go because you are forcing extra JMP's at the assembly level for function calls.

If builder functions are purely setters, they will probably all be inlined anyway.

1 Like

For this kind of function, which crafts some message according to a protocol and where all the arguments are required, I don't really think there's a problem with this. In the end you're still going to need something like a ProcessedPacketHeader { [insert twenty fields here] } anyway.

Just create a struct to use for passing the arguments. This way the names of the fields determine the fields and not the ordering, which eliminates the typical problems with lots of arguments.

6 Likes