Anche questo fa la stessa cosa
byte Val=PINA;
byte bit_0 = bitRead(Val, 0); //resituisce 0 o 1
byte bit_1 = bitRead(Val, 1); //resituisce 0 o 1
byte bit_2 = bitRead(Val, 2); //resituisce 0 o 1
...
...
dove PINA non è la moglie di Fantozzi

, ma il byte restituito che raccoglie lo status degli 8 pin
ad esempio nella 2560 i bit appartengono a questi pin
// PA 7 ** 29 ** D29
// PA 6 ** 28 ** D28
// PA 5 ** 27 ** D27
// PA 4 ** 26 ** D26
// PA 3 ** 25 ** D25
// PA 2 ** 24 ** D24
// PA 1 ** 23 ** D23
// PA 0 ** 22 ** D22
dovrei fare un test di efficienza tra questa funzione e quella di Mauro... oramai siamo in ballo

ciao
Lo scritto altre volte, la velocità è importante solo dopo avere sviluppato il programma per fornire le funzionalità richieste, se dopo ci si accorge
che dobbiamo fare di meglio, si può rinunciare alla chiarezza del codice in favore della pura velocità.
In campo professionale, si fa pressione sui sviluppatori software al fine di fornire le funzionalità richieste con l'hardware specificato. In altre parole devi usare
questo hardware è scrivere un software con queste funzionalità e non si accettano ma.
In campo obbistico invece si passa ad un microcontroller con maggiore velocità, tuttavia Arduino non ha un numero illimitato di board quindi alla fine se hai la MEGA quella ti devi fare bastare e se non è sufficientemente reattiva devi cercare di ottimizzare.
Comunque le macro che hai postato le preferisco alle strutture bitfield, quelle macro non fanno altro che usare le bitwise per estrarre il valore di un solo bit. Però c'è un però se devi valutare l'uno dopo l'altro il contenuto di 10 variabili bit per bit e facile che ti ritrovi con tante variabili di tipo byte che contengono un solo bit, in tal caso le strutture bitfield sono da preferire, ma sono più complicate perchè devi assegnare un valore ad una struttura devi lavorare con i puntatori e il cast.
PS: io non mi metto a fare test, ma mi piace seguire chi li fa, quindi apri un post che lo seguo.
Ciao.