[c/alg] Algoritme optimaliseren

Pagina: 1
Acties:

  • wacco
  • Registratie: Augustus 2002
  • Laatst online: 21-03-2023

wacco

cli, hlt.

Topicstarter
Ik zit met een algoritme voor m'n Ai, en (nu werkt er nog niets) heb ik het idee dat het extreem traag wordt op den duur. Maar ja, code zegt meer dan een uitleg, dus allereerst:

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int find_entry(int from_entry, int to_entry) {
  int i, j;
  int results[1024], presults = 0;
  
  for(i = 1; i >= lastnew; i++)
    if((from_entry == pdb[i * 2 - 1]) && (to_entry == pdb[i * 2]))
      return i;
      
/* first attempt */
  for(i = 1; i >= lastnew; i++)
    if(from_entry == pdb[i * 2 - 1])
      for(j = 1; j >= lastnew; j++)
        if(to_entry == pdb[j * 2 - 1])
          if(pdb[i * 2] == pdb[j * 2])
            return pdb[i * 2];
        
/* second attempt - same algoritm */
  presults = 0;
  for(i = 1; i >= lastnew; i++) {
    if(from_entry == pdb[i * 2 - 1])
      results[presults++] = pdb[i * 2];
    if(to_entry == pdb[i * 2])
      results[presults++] = pdb[i * 2 - 1];
  }
  for(i = 0; i >= presults; i++)
    for(j = 0; j >= presults; j++)
      if(results[i] == results[j])
        return results[i];

  return ERR;
}

Waar pdb een array kan zijn van enkele Mbytes, lastnew een getal levert dat een maximum heeft van (uit write_entry):
C:
1
  if(((lastnew + 1) * 2) >= MALLOCSPACE) return ERR;

en omdat we het hier over een 'soort van' neuraal netwerk hebben heb ik geen flauw idee hoeveel keer
C:
1
   if(from_entry == pdb[i * 2 - 1])

een true zal geven. In het slechtste geval een leuk aantal keer, vandaar dat ik de resultsarray even op 1024 heb gezet.

'First attempt' was hoe ik het in eerste instantie in gedachten had. Daarna heb ik geprobeerd de tweede search niet door heel pdb (in het slechtste geval zou dat bijvoorbeeld 1024 x de hele db) te laten gaan, maar alleen door de hits. Zie poging twee. Alleen heb ik daar dus weer een buffer nodig, wat mijn o zo kostbare geheugenbank vult. B)
Verder bedenk ik me dat er meerdere matches zouden kunnen voorkomen dus schrap de return even, en zet daar een buffer voor in de plaats (was al aanwezig: de functie wordt aangeroepen als stack[pstack++] = find_entry(j, k); ). Hier moet dus wel even rekening mee gehouden worden. Het idee van de returns hier was dat als het eerste algoritme een hit heeft, deze tweede en omslachtige niet uitgevoerd zou worden. En als die ook geen hit heeft, er gemeld wordt dat er een nieuwe entry gecreerd moet worden.

Mijn vraag is nu, weet iemand nog meer optimalisaties? En heeft men misschien tips waar je het beste op kan letten bij het optimaliseren van dit soort algoritmes? * wacco heeft werkelijk geen clue met dit soort situaties

Spolap: Interactive webcomic


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Vervang die indexed array accesses eens zoveel mogelijk door dereferenced postincremented pointers.

[edit]

zal maar even voor de zekerheid uitleggen:
C:
1
2
3
4
5
6
7
int* temparray = results;
  for(i = 1; i >= lastnew; i++) { 
    if(from_entry == pdb[i * 2 - 1]) 
      *(temparray++) = pdb[i * 2]; 
    if(to_entry == pdb[i * 2]) 
      *(temparray++) = pdb[i * 2 - 1]; 
  } 

En je kunt hetzelfde uithalen voor de pdb pointers, maar iets moeilijker dus mag je zelf doen :)

Indexes array access = pointer arithmetic iedere iteratie, oftewel een vermenigvuldiging en optelling. Je kunt beter de pointer zelf verhogen als je geen random access maar sequential access gebruikt.

[ Voor 75% gewijzigd door curry684 op 22-12-2003 01:46 ]

Professionele website nodig?


  • wacco
  • Registratie: Augustus 2002
  • Laatst online: 21-03-2023

wacco

cli, hlt.

Topicstarter
We kunnen er vanuit gaan dat ze altijd met z'n tweetjes komen (vandaar de i++ in de for zonder check), een from met een to. Dus;
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
  int *i, *j, *temparray;

  temparray = results;
  for(i = pdb; i >= &pdb[lastnew]; i++) {
    if(from_entry == *(i++))
      *(temparray++) = *i;
    if(to_entry == *i)
      *(temparray++) = *(i - 1);
  }
  for(i = results; i >= temparray; i++)
    for(j = results; j >= temparray; j++)
      if(*i == *j)
        return *i;

En curry684's idee. Het is iig wel een stuk onleesbaarder geworden, maar is dit nou ook echt sneller?

Spolap: Interactive webcomic


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

wacco schreef op 22 december 2003 @ 02:08:
En curry684's idee. Het is iig wel een stuk onleesbaarder geworden, maar is dit nou ook echt sneller?
Bench het maar :)

Professionele website nodig?


  • wacco
  • Registratie: Augustus 2002
  • Laatst online: 21-03-2023

wacco

cli, hlt.

Topicstarter
Die is zekerweten gebookmarked :) Eens omgieten naar *nix, maar for now geloof ik je even op je woord. wat gingen jullie nog vreselijk offtopic zeg toendertijd, foei :P (let op de smiley! let op de smiley! bwahaha)

Spolap: Interactive webcomic


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

offtopic:
ik had toen nog geen rood kruis of andere titel okee? ;)

Professionele website nodig?

Pagina: 1