idee per velocizzare ricerca dati in array?

MauroTec:
Se i dati di MyArray sono quelli allora si può evitare la ricerca.

MyArray[10]={5,10,20,30,40,50,60,70,80,90};
MyArray[0] = 5
MyArray[1] = 10
MyArray[2] = 20
MyArray[3] = 30
MyArray[4] = 40
MyArray[5] = 50
MyArray[6] = 60
MyArray[7] = 70
MyArray[8] = 80
MyArray[9] = 90

aNumber = 38

min = aNumber/10 = 3
max = aNumber/10 + 1 = 4
MyArray[min]
MyArray[max]

Sembra funzionare

Provo con 7

aNumber = 7
min = aNumber/10 = 0
max = aNumber/10 + 1 = 1

Sembra funzionare

Provo con 2

aNumber = 2
min = aNumber/10 = 0
max = aNumber/10 + 1 = 1

Funziona come per aNumber = 7

mmm.. se fossero così pochi i dati potresti anche fare uno switch case
che è molto rapido in esecuzione.

Sicuramente i dati nell'array non sono quelli reali per cui vai di ricerca dicotomica.

Se fai come dice gpb01 e usi i puntatori e una funzione ricorsiva dovresti ottenere il massimo della velocità
possibile, almeno io un altro modo più rapido non lo conosco.

Ciao.

il metodo che hai postato credo funzioni, si somiglia ad uno che fa la stessa cosa che ho trovato dentro uno sketch di una tesi di laurea di un Laureando in "Automotive Electronics Engineering" inglese che ha realizzato con arduino una centralina per motore monocilindrico con controllo Lambda e battito in retroazione (!) e dai filmati visti su yotube il motorino funziona benino. Rispetto al mio codice è veramente ridotto all'osso, alcune cose le ho capite, tra cui, la tecnica per fare come hai indicato te, per esempio, nell'esempio che ho fatto di array, i valori indicati in essa, stanno arappresentare i gradi apertura farfalla, quindi se essi sono regolarmente distribuiti dividiamo per il valore che li separa uno dall'altro ed otteniamo un intero, che dovrebbe corrispondere con il valore dell'index array che lo contiene, ma non è molto efficiente se i valori in array non sono lineari.

@Guglielmo:

Grazie del chiarimento, era questo a cui mi riferivo prima, avevo letto qualcosa al riguardo della ricerca binaria e che è il metodo più veloce esistente in C per ricercare in arrays, il mio dubbio era se potevo applicare quella tecnica ad una MCU visto che il libro di cui parlo, tratta programmazione su Computer tradizionali, quindi non sistemi Embedded. Adesso vedo che la cosa è fattibile.

@Nid69ita:

ho fatto un test con array a 16 elementi, fa la ricerca sia con il metodo mio, che con il metodo suggerito da te, Avevi Ragione, il compilatore forse già ottimizza l'IF con operatore &&, infatti, i risultati sembrano essere identici, ho dovuto solo modificare uno dei operatori di comparazione perché se capitava un valore a metà strada tra quello inferiore e superiore, spesso il risultato era incerto, mentre così modificato, è perfetto.

Ecco il codice completo:

//*******************************************************************
//**    TEST TEMPO DI ESECUZIONE RICERCA INDICE ARRAY
//*******************************************************************

byte i;

byte MyArray[ 10 ] = {10,20,30,40,50,60,70,80,90,100};
 
unsigned long Tempo_Start=0;
unsigned long Tempo_Fine=0;
unsigned long Tempo_Delta=0;

byte Valore_Ricercato;
byte Val_Ricercato_inf;
byte Val_Ricercato_sup;

//*******************************************************************
void setup(){
  
 Serial.begin(9600); 
 
  
}

//*******************************************************************
void loop(){
 
 Valore_Ricercato = map (analogRead(A0),0,1023,0,100);
  
 Tempo_Start=micros();
 
 //per testare i due metodi, semplicemente escludere l'altro metodo
 //commentandolo in blocco.


//---metodo 1: Suggerito da Nid69ita--------- esegue da 4 a 20 uS 
//(4 quando il valore ricercato é nel primo index e 20 quando è l'ultimo index dell'array)

/*
 for (i = 0; i < 10; i++)
{ if (Valore_Ricercato >= MyArray[ i ])
    if( Valore_Ricercato < MyArray[ i + 1 ] )
    {  Val_Ricercato_inf = MyArray[ i ];
       Val_Ricercato_sup = MyArray[ i + 1 ]; 
       break;
    }
}
*/
//---metodo 2: il mio (hiperformance71)--- esegue in: 4 a 20 uS
//(4 quando il valore ricercato é nel primo index e 20 quando è l'ultimo index dell'array)

/*
for ( i = 0; i < 10; i++ )
{
if (Valore_Ricercato >= MyArray[ i ]  &&  Valore_Ricercato < MyArray[ i + 1 ] )
{
Val_Ricercato_inf = MyArray[ i ]; 
Val_Ricercato_sup = MyArray[ i + 1 ];
break;
}
}
*/
//---metodo 3: suggerito da MauroTec ----

Val_Ricercato_inf = Valore_Ricercato / 10;
Val_Ricercato_sup = Valore_Ricercato / 10 + 1;

Tempo_Fine=micros();
Tempo_Delta = Tempo_Fine - Tempo_Start;

Serial.print(i);
Serial.print(",");
Serial.print(Valore_Ricercato);
Serial.print(",");
Serial.print(Val_Ricercato_inf);
Serial.print(",");
Serial.print(Val_Ricercato_sup);
Serial.print(",");
Serial.println(Tempo_Delta);
  
}

ho voluto approfittare per includere anche il test del suggerimento di MauroTec, ed effettivamente, già così, è il più veloce e non viene influenzato dallo stato del Valore_Ricercato mentre gli altri metodi basati su FOR/IF per forza di cose, dipendendo da dove si trova il valore ricercato, incidono sul risultato. Questo impiega 8 uS, ma, diversamente dagli altri metodo, questa ricerca viene eseguita una volta a ciclo di loop() e non in un unico loop() come i FOR/IF, quindi quanto attendibile è eseguire 10 ricerche in 10 cicli loop? è giusto pensare al prodotto matematico, ovvero 8 uS x 10 loop = 80 uS ? se così fosse, allora sarebbe peggio dei FOR/IF, mamma mia, adesso sono più confuso! Purtroppo, come accennato prima, questo metodo funzionerebbe se, come in questo caso, i valori in array fossere spaziati in modo regolare, quindi multipli direi, diversamente ho verificato tende a sbagliare alla fine (avevo fatto una prova con array a 16 elementi, così => {0,2,5,7,10,12,15,20,30,40,50,60,70,80,90,100} ovviamente, il fatto di avere 16 elementi e non 10 ha mandato a monte il sistema, non ho verificato se usando /16 invece di /10 funziona. magari provo dopo.

Poi vedrò di studiare come fare per la ricerca binaria e fare un test in questo sketch.

PS. per come mi serve a me, non servirebbe nemmeno il select/case, avere già il riferimento dell'index inferiore e superiore già mi basta per poi inserirlo dentro la funzione che mi prende i valori nella mappa vera e propia per calcolare l'interpolazione lineare tra i due valori estratti da essa corrispondenti appunto dentro gli index appena trovati.
Resta da chiarire, in che modo possano essere vantaggiosi uno o l'altro metodo, dal mio modesto punto di vista, essere più veloce nell'esecuzione di un loop() lascia spazio ad una esecuzione più veloce ed efficiente di tutti i restanti componenti di codice, ma implica fare il tutto in più cicli clock, farlo con i FOR/IF aumenta il tempo richiesto per ciclo di loop() ma garantisce un calcolo finito, ancora non so quale dei due mi convenga, in realtà, dovrò suddividere tutte le operazioni in diverse funzioni che verranno chiamate in causa da un sistema schedulatore in base alla priorità che ogni funzione avrà, ci saranno funzioni che saranno chiamate più spesso ed altre a cadenze più lunghe perchè hanno dati che cambiano lentamente )come le temperature motore, temp. aria ecc che cambiano ogni 0,5-1 sec, quindi è inutile chiamarle ad ogni ciclo loop).