[C] case voor een bereik

Pagina: 1
Acties:

  • Blaurens
  • Registratie: Mei 2002
  • Laatst online: 29-04 01:15
Ik wil graag switch/case gebruiken, maar dan voor een bepaald bereik. Dus, ipv:

C:
1
2
3
4
5
6
7
8
9
10
11
12
switch (example)
{
    case 1:
    case 2:
    case 3:
    case 4:
        printf("1-4\n");
        break;  
    default:
        printf("Something else\n");
        break;
}


zou ik graag iets doen als

C:
1
2
3
4
5
6
7
8
9
switch (example)
{
    case 1..4:
        printf("1-4\n");
        break;  
    default:
        printf("Something else\n");
        break;
}


Bij gooooooogle kan ik dat uiteraard niet vinden, dus iemand suggesties of en hoe dit zou kunnen? Tnx!

[ Voor 172% gewijzigd door Blaurens op 17-02-2004 14:40 . Reden: Tevroeg op enter geduwd. ]


Verwijderd

Ehhm, dat werkt toch ook zo (bovenste voorbeeld)?
(korter kan volgens mij niet in een switch)

[ Voor 32% gewijzigd door Verwijderd op 17-02-2004 14:41 ]


  • Blaurens
  • Registratie: Mei 2002
  • Laatst online: 29-04 01:15
Ja, maar het is natuurlijk niet zo fijn als je diverse bereiken van 50 moet controleren op die manier. Bovendien kan je dan niet echt lekker werken met constanten.

Verwijderd

Dan worden het toch IF-jes denk ik

  • Blaurens
  • Registratie: Mei 2002
  • Laatst online: 29-04 01:15
Misschien iets voor C+=2 dan :)

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

curry684

left part of the evil twins

Een switch kan alleen op een absolute match van constantes. IF-jes dus.

Professionele website nodig?


  • Macros
  • Registratie: Februari 2000
  • Laatst online: 30-04 09:28

Macros

I'm watching...

Als je ifjes gebruikt, misschien moet je dan een beetje een binaire boom structuur gebruiken. Dan limiteer je de hoeveelheid if evaluaties die je moet doen.

"Beauty is the ultimate defence against complexity." David Gelernter


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22-05 16:53
Schrijf een in_range( ... ) functie en los het op met ifjes, is ontzettend duidelijk en nog kort ook.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Dit kun je in C (en C++) alleen met IFjes oplossen. Ik geloof dat het in delphi wel kan: in de vorm die je zelf als voorbeeld geeft.

Verwijderd

C:
1
2
3
4
5
6
7
8
9
10
11
12
switch (example) 
{ 
    case 1:
    case 2:
    case 3:
    case 4: 
        printf("1-4\n"); 
        break;     
    default: 
        printf("Something else\n"); 
        break; 
}


wat is daar mis mee? het werkt toch :?

Zolang je een klein lijstje hebt is het goed lijkt me, maar als het 100 worden, tja...

[ Voor 35% gewijzigd door Verwijderd op 17-02-2004 22:52 ]


Verwijderd

C:
1
2
3
case 1 ... 4:
  ..
  break;


Is een gcc-extensie. :).

  • Blaurens
  • Registratie: Mei 2002
  • Laatst online: 29-04 01:15
Beelzebubu: Thanks a LOT! Laat ik nou (in beginsel om budgetaire redenen) gcc gebruiken :) Precies de oplossing die ik zocht! En ik was nog op de goede weg met mijn gok ook :)

Wiegje: Ja, het werkt prima, maar het gaat om een aantal grote bereiken, dus is het niet practisch.

Farlane: Dat was denkik de optie geworden als Beelzebubu niet gepost zou hebben :)

Macros: weet niet precies wat je bedoelt, maar ik zou het met veel else dingen opgelost hebben, als dat is wat je bedoelde. Dat, gecombineerd met Farlane's suggestie.

[ Voor 1% gewijzigd door Blaurens op 18-02-2004 10:52 . Reden: typo ]


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

curry684

left part of the evil twins

Blaurens schreef op 18 februari 2004 @ 10:52:
Beelzebubu: Thanks a LOT! Laat ik nou (in beginsel om budgetaire redenen) gcc gebruiken :) Precies de oplossing die ik zocht! En ik was nog op de goede weg met mijn gok ook :)
[onsubtiele rant-mode]

Compiler-specific extensies :r :r :r :r :r :r

Professionele website nodig?


  • Macros
  • Registratie: Februari 2000
  • Laatst online: 30-04 09:28

Macros

I'm watching...

Lijkt me ook een slecht idee om non-standaard manier te gebruiken om het op te lossen.

Stel je voor je hebt een gesorteerde array en je zoekt de plek van een getal in die array. Dan neem je het midden van de array, kijkt ofdat lager, hoger of gelijk is aan het getal dat je zoekt. Is het gelijk dan heb je het gevonden, is het lager of hoger, dan moet je in het onderste of bovenste gedeelte van de array verder zoeken. Volgens mij is die techniek ook toepasbaar op dit probleem.

"Beauty is the ultimate defence against complexity." David Gelernter


  • igmar
  • Registratie: April 2000
  • Laatst online: 12-05 15:46

igmar

ISO20022

Verwijderd schreef op 18 februari 2004 @ 01:13:
C:
1
2
3
case 1 ... 4:
  ..
  break;


Is een gcc-extensie. :).
Heeeeeeeeerlijk portable :) Om maar eens wat OT te worden ? Is d'r ergens een lijst met gcc specifieke zaken te vinden ? 'extensions' bedoelt men over het algemeen wat anders mee, dus Google laat me in deze in de steek :(

[ Voor 32% gewijzigd door igmar op 18-02-2004 12:42 ]


  • Blaurens
  • Registratie: Mei 2002
  • Laatst online: 29-04 01:15
curry684 schreef op 18 februari 2004 @ 11:27:
[...]
Compiler-specific extensies :r :r :r :r :r :r
Daar ben ik het volledig mee eens. Alleen is dit een klein one-man project, waar ik waarschijnlijk over een tijdje nooit meer naar omkijk, en met mij verder ook niemand. Maargoed, ik zal er wat // bijzetten.

Inderdaad, niet standaard is niet fijn :)

Then again, om even off-topic te geraken, als iedereen zich aan standaarden houdt, waar komt evt. innovatie dan vandaan?
Macros schreef op 18 februari 2004 @ 12:17:
Lijkt me ook een slecht idee om non-standaard manier te gebruiken om het op te lossen.

Stel je voor je hebt een gesorteerde array en je zoekt de plek van een getal in die array. Dan neem je het midden van de array, kijkt ofdat lager, hoger of gelijk is aan het getal dat je zoekt. Is het gelijk dan heb je het gevonden, is het lager of hoger, dan moet je in het onderste of bovenste gedeelte van de array verder zoeken. Volgens mij is die techniek ook toepasbaar op dit probleem.
Ja, maar da's niet de snelste optie (dit moet meerdere malen per seconde), werkt het het beste met een gelijkmatig verdeelde array, maw: voor mij op dit moment in ieder geval niet een ideale oplossing.

[ Voor 43% gewijzigd door Blaurens op 18-02-2004 13:04 ]


  • Macros
  • Registratie: Februari 2000
  • Laatst online: 30-04 09:28

Macros

I'm watching...

Het is sneller dan normaal if'jes toe te passen, wat een worst case heeft van het aantal bereiken en een average case van de helft. Terwijl binary search log2 heeft als worst case.

"Beauty is the ultimate defence against complexity." David Gelernter


Verwijderd

Extensies zijn inderdaad iets waar je schaterlachend je middelvinger naar op zou moeten steken. De "if ... else if ... else" constructie lijkt me ook het beste maar puur uit morbide curiositeit een implementatie met de preprocessor, ongetest maar zou moeten werken.

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#define CASE(a)     case a
#define CASE(a,b)       CASE(b): case a
#define CASE(a,b,c)     CASE(b,c): case a
#define CASE(a,b,c,d)   CASE(b,c,d): case a
#define CASE(a,b,c,d,e) CASE(b,c,d,e): case a
// ... etc

switch(waarde) {
    CASE(1, 2, 3, 7, 1124):
        // ... doe iets
        break;
    default:
        // ... doe iets anders
        break;
}


Met behulp van templates en metaprogramming technieken moet je het naar mijn weten écht kunnen oplossen; het opgeven van enkel begin en einde van de reeks zou compile-time automatisch de "case" statements moeten kunnen genereren.

[ Voor 3% gewijzigd door Verwijderd op 18-02-2004 13:20 ]


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

curry684

left part of the evil twins

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <stdio.h>

int FindRange(int p_Input, int *p_LowBound, int *p_HighBound)
{
static int c_RangeSeparators[] = { 0, 5, 55, 90, 200, 210, 350, 360, 370 };
static int c_RangeCount        = sizeof(c_RangeSeparators) / sizeof(int);

register int   l_High  = c_RangeCount;
register int   l_Low   = 0;
register int   l_Pivot;

if(p_Input < c_RangeSeparators[0] || p_Input > c_RangeSeparators[c_RangeCount - 1])
  return -1;    // Error
while(l_Low + 1 < l_High)
  {
  l_Pivot = (l_Low + l_High) / 2;
  if(p_Input < c_RangeSeparators[l_Pivot])
    l_High = l_Pivot;
  else
    l_Low  = l_Pivot;
  }
*p_LowBound  = c_RangeSeparators[l_Low];
*p_HighBound = c_RangeSeparators[l_High];
return l_Low;
}

void TestRange(int p_Input)
{
int   l_Low, l_High, l_Index;
l_Index = FindRange(p_Input, &l_Low, &l_High);
if(l_Index < 0)
  printf("Input %d is not valid\n", p_Input);
else
  printf("Input %d is in range %d-%d (idx %d)\n", p_Input, *l_Low, *l_High, l_Index);
}

int main()
{
TestRange(5);
TestRange(154);
TestRange(7653);
TestRange(123);
TestRange(342);
TestRange(65);
TestRange(-50);
TestRange(205);
return 0;
}

Geeft als output:
code:
1
2
3
4
5
6
7
8
Input 5 is in range 5-55 (idx 1)
Input 154 is in range 90-200 (idx 3)
Input 7653 is not valid
Input 123 is in range 90-200 (idx 3)
Input 342 is in range 210-350 (idx 5)
Input 65 is in range 55-90 (idx 2)
Input -50 is not valid
Input 205 is in range 200-210 (idx 4)

Veel plezier, hiermee kun je gewoon zoals het hoort switchen op de index van de range, en gebruik je wel de binary ultrafast lookups :)

[ Voor 2% gewijzigd door curry684 op 18-02-2004 13:49 . Reden: oeps C++ gewend, references veranderd in pointers :) ]

Professionele website nodig?


Verwijderd

Waarom dan niet gewoon het volgende, als de ranges toch fixed zijn?
C:
1
2
3
4
5
6
7
8
9
10
#define range(I,L,H) ((I) >= (L) && (I) <= (H))

if(range(n, 0, 4))
  // ... doe iets
else if(range(n, 5, 54))
  // ... doe iets anders
else if(range(n, 55, 89))
  // ... doe het, schatje!
else
  // ... valt niet binnen bereik

Op die manier heb je geen functies (ook als je "range" als functie zou implementeren of gewoon uitcoderen is het een STUK sneller). Als je de bereiken op één plek wilt houden is dat ook best te doen door de bovenstaande if .. else-jes in één functie te pleuren. Daarbij kan je hier tenminste gaten in je bereik laten vallen mocht dat nodig zijn.

p.s. Het gebruik van bovenstaande macro is niet bepaald veilig, maar het is iig duidelijk wat er bedoeld wordt.

[ Voor 10% gewijzigd door Verwijderd op 18-02-2004 14:22 ]


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

curry684

left part of the evil twins

Verwijderd schreef op 18 februari 2004 @ 14:19:
Waarom dan niet gewoon het volgende, als de ranges toch fixed zijn?
Omdat de O(log n) oplossing van mij verdomd rap jou O(n) oplossing inhaalt als er een flink aantal ranges zijn. Met 50 ranges doe ik namelijk 6 compares worst-case, jij 50. Bij 200 ranges zit ik op 8 tegenover 200 voor jou :)

Daarnaast zijn de ranges bij mij helemaal niet fixed als je ze globaal maakt ipv static in die functie :z

En wat betreft gaten in het bereik:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
switch(FindRange(...))
  {
  case 0:
    ...
  case 2:
    ...
  case 3:
    ...
  case 4:
    ...
  default:
    printf("Illegal input!\n");
  }

Ik zie het probleem niet zo?

[ Voor 33% gewijzigd door curry684 op 18-02-2004 14:27 ]

Professionele website nodig?


Verwijderd

Ik ben het niet volledig oneens met de kritiek die men geeft (extensies zijn idd. niet echt enorm portable), maar serieus: al die andere "oplossingen" die ik hier zie zijn zulke enorm ultra-gora hacks dat ik me nog wel 10x erger zou schamen als ik die gebruikte dan met de huidige gcc-only oplossing. Dan liever een gcc-extensie, totdat ISO C met een echte oplossing komt.
igmar schreef op 18 februari 2004 @ 12:22:
Heeeeeeeeerlijk portable :) Om maar eens wat OT te worden ? Is d'r ergens een lijst met gcc specifieke zaken te vinden ? 'extensions' bedoelt men over het algemeen wat anders mee, dus Google laat me in deze in de steek :(
http://gcc.gnu.org/online...x.html#toc_C%20Extensions is (geloof ik) de officiele lijst.

edit:
Trouwens, curry, leuke sig, maar ik verdien aardig goed aan de opensource business hoor... Vreemde sig...


edit:
Macros: support, maar ook development of service providing. Niet alle software wordt als zulks verkocht. ;). En via de LGPL kun je natuurlijk delen closed-source houden.

[ Voor 23% gewijzigd door Verwijderd op 18-02-2004 15:46 ]


  • Macros
  • Registratie: Februari 2000
  • Laatst online: 30-04 09:28

Macros

I'm watching...

Mooie implementatie Curry.
offtopic:
Met open-source is de software open, maar de support op die software niet, daardoor kan je geld verdienen met open-source

"Beauty is the ultimate defence against complexity." David Gelernter


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

curry684

left part of the evil twins

Verwijderd schreef op 18 februari 2004 @ 15:33:
Ik ben het niet volledig oneens met de kritiek die men geeft (extensies zijn idd. niet echt enorm portable), maar serieus: al die andere "oplossingen" die ik hier zie zijn zulke enorm ultra-gora hacks dat ik me nog wel 10x erger zou schamen als ik die gebruikte dan met de huidige gcc-only oplossing. Dan liever een gcc-extensie, totdat ISO C met een echte oplossing komt.
Ik zie niet in hoe mijn type-safe ultrasnelle easy-adaptable-and-extendable code in de categorie 'ultra-gore hacks' terechtkomt? :?
edit:
Trouwens, curry, leuke sig, maar ik verdien aardig goed aan de opensource business hoor... Vreemde sig...
offtopic:
Dus, stel dat ik morgen een goed idee heb voor een applicatie, en ik schrijf die compleet als opensource, hoe schets jij dan het scenario waarin ik daarvan stinkend rijk wordt?

De open-source economie is elitairder en monopolistischer dan de kapitalistische economie: de happy few verdienen al het zeldzame geld wat er in omgaat, in plaats van dat iedereen een faire kans heeft om fortuin te verdienen aan z'n ideeen en capaciteiten. Klinkt bijna communistisch :z

Stel dat Cerulean Studios hun flagship product Trillian als open-source had ontwikkeld: gaat er iemand support aanschaffen op een instant messenger? No way, ergo ze hadden niet kunnen bestaan. Nu hebben ze een constante bron van inkomsten waarmee ze een aantal medewerkers uit de WW houden, de staatskas daarmee ontlasten, en fulltime innovatieve ideeen kunnen ontwikkelen. Een open-source project van dat formaat levert gewoon niemand geld op en is daarmee a) een ramp voor de economie en b) een ramp voor softwaredevelopment, omdat mensen die varierend 0-40 uur per week 'hobbyen' nu eenmaal niet dezelfde innovatie en ontwikkelsnelheid kunnen vertonen die een team van fulltime programmeurs onder een baas die met harde hand regeert aan de dag kunnen leggen. Open source is een ramp voor de software development van deze wereld zodra er geen commerciele software meer is om te imiteren.

[ Voor 27% gewijzigd door curry684 op 18-02-2004 15:49 ]

Professionele website nodig?


Verwijderd

curry684 schreef op 18 februari 2004 @ 15:44:
Ik zie niet in hoe mijn type-safe ultrasnelle easy-adaptable-and-extendable code in de categorie 'ultra-gore hacks' terechtkomt? :?
Het feit dat de gcc-extensie sneller is en minder code heeft. Lijkt me nogal voor-de-hand-liggend. Die van jou is idd. geen "ultra-gore hack" zoals die CASE() macro zooi hierboven, maar feit blijft dat 'ie niet zo snel'n'simple is als de gcc-extensie.
offtopic:
Dus, stel dat ik morgen een goed idee heb voor een applicatie, en ik schrijf die compleet als opensource, hoe schets jij dan het scenario waarin ik daarvan stinkend rijk wordt?

De open-source economie is elitairder en monopolistischer dan de kapitalistische economie: de happy few verdienen al het zeldzame geld wat er in omgaat, in plaats van dat iedereen een faire kans heeft om fortuin te verdienen aan z'n ideeen en capaciteiten. Klinkt bijna communistisch :z
Wil je dat ik hierbinnen reageer of liever prive/ander_topic? Zie voor de rest de edit in mijn vorige reply. En de vergelijking met het communisme is zo oud... :{.

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

curry684

left part of the evil twins

Verwijderd schreef op 18 februari 2004 @ 15:49:
[...]


Het feit dat de gcc-extensie sneller is en minder code heeft. Lijkt me nogal voor-de-hand-liggend. Die van jou is idd. geen "ultra-gore hack" zoals die CASE() macro zooi hierboven, maar feit blijft dat 'ie niet zo snel'n'simple is als de gcc-extensie.
I doubt it. GCC kan echt niet meer met die hack van hun doen dan 'm expanden naar een rits if-jes, en dus per definitie langzamer dan een goede bsearch implementatie.
Wil je dat ik hierbinnen reageer of liever prive/ander_topic? Zie voor de rest de edit in mijn vorige reply. En de vergelijking met het communisme is zo oud... :{.
Ik heb bijge-edit :) En nee, de discussie hoeft hier niet verder, GoT is helaas niet een plek waar je zo een discussie clean kunt voeren met enkel de mensen die recht van spreken hebben over het onderwerp en niet enkel /.-punchlines kunnen ranten.

Communisme bleek trouwens ook pas dat het niet werkte toen het na een tijdje geolied begon te draaien. En dat een vergelijking vaak gemaakt wordt betekent niet dat ie per definitie ongeldig is, maar dat er wellicht door veel mensen een grond van waarheid in gezien wordt :Y)

[ Voor 13% gewijzigd door curry684 op 18-02-2004 15:56 ]

Professionele website nodig?


  • Gondor
  • Registratie: September 2003
  • Laatst online: 19:54
code:
1
2
3
4
5
6
7
8
9
switch (example)  
{  
    case 1 ... 4: 
        printf("1-4\n");  
        break;      
    default:  
        printf("Something else\n");  
        break;  
}

code:
1
2
3
4
5
6
if (1=<example=<4)  
{  
    printf("1-4\n");  
} else {
    printf("Something else\n");  
}


Tweede code lijkt mij toch korter.

edit:
was '}' vergeten

[ Voor 14% gewijzigd door Gondor op 18-02-2004 16:00 ]

"Peace cannot be kept by force. It can only be achieved by understanding"-Albert Einstein-


Verwijderd

curry684 schreef op 18 februari 2004 @ 15:55:
I doubt it. GCC kan echt niet meer met die hack van hun doen dan 'm expanden naar een rits if-jes, en dus per definitie langzamer dan een goede bsearch implementatie.
Zou gcc niet expanden naar "case lowest: case lowest+1: ... case highest-1: case highest: .. break;"? Dat heb ik altijd aangenomen. En het lijkt me dat zo'n lookup sneller is dan een serie ifjes (wat jouw implementatie feitelijk dus ook doet).
Communisme bleek trouwens ook pas dat het niet werkte toen het na een tijdje geolied begon te draaien. En dat een vergelijking vaak gemaakt wordt betekent niet dat ie per definitie ongeldig is, maar dat er wellicht door veel mensen een grond van waarheid in gezien wordt :Y)
/me mompelt over flauwe redenatie. Leuk boek voor jou: "Wilde Zwanen", gaat over het ontstaan en het mislukken van het communisme in China voor en na de revolutie. ;). Maargoed, die discussie houden we ooit wel ergens anders dan. :).

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:03
Ik weet niet in welke taal dat tweede stukje geschreven is, maar het is geen C. ;) Verder heb je gelijk, maar de reden om case te gebruiken in plaats van een serie if-jes is dat de compiler die vaak makkelijk kan implementeren met een jump-table; je hebt dan een lookup in constante tijd in plaats van in lineaire tijd. curry684 probeert de boel nog een beetje te redden met een lookup in logaritmische tijd, maar om eerlijk te zijn betwijfel ik of die code daadwerkelijk efficienter is als je maar een stuk of 10 cases onderscheidt.

Sowieso zou ik zelf omwille van de helderheid gewoon if-jes gebruiken, tenzij het zowel om veel ranges gaat en het case-statement van cruciaal belang is voor de performance van het geheel.

Verwijderd

curry684 schreef op 18 februari 2004 @ 14:24:Omdat de O(log n) oplossing van mij verdomd rap jou O(n) oplossing inhaalt als er een flink aantal ranges zijn. Met 50 ranges doe ik namelijk 6 compares worst-case, jij 50. Bij 200 ranges zit ik op 8 tegenover 200 voor jou :)
Ik geloof onmiddelijk dat de binary search bij een grote hoeveelheid bereiken efficiënter is, echter ga je voorbij aan het feit dat de functie die je gebruikt relatief "groot" is; meerdere compares (de while is ook een compare tenslotte), een aantal assigns en operators (toegegeven; kost weinig, maar bij enkel ifjes heb je ze helemaal niet) en nog wat dingen. De redenering die jij gebruikt voor performanceverschil is dus niet volledig, de enige manier op zekerheid is testen
En wat betreft gaten in het bereik:
Elk gat is in jouw routine een extra bereik en daardoor extra tijd, voor ifjes maakt het eigenlijk niets uit.

Niet dat ik je methode af wil kraken ofzo, het ziet er zeker wel netjes uit, ik heb alleen het idee dat het overkill is in dit geval. Maar eigenlijk is hier pas écht iets over te zeggen als we wat meer over de betreffende ranges weten zoals hoeveel, hoe groot, komen ze allen even vaak voor, etc.

Overigens; hoe presteren de STL containers voor dit soort situaties?

  • Gondor
  • Registratie: September 2003
  • Laatst online: 19:54
Ah :D , moest zijn:
code:
1
2
3
4
5
6
if ( (1<=example) && (example<=4) )
{
    printf("1-4\n");
} else {
    printf("else\n");
}

"Peace cannot be kept by force. It can only be achieved by understanding"-Albert Einstein-


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

curry684

left part of the evil twins

Soultaker schreef op 18 februari 2004 @ 16:07:
Ik weet niet in welke taal dat tweede stukje geschreven is, maar het is geen C. ;) Verder heb je gelijk, maar de reden om case te gebruiken in plaats van een serie if-jes is dat de compiler die vaak makkelijk kan implementeren met een jump-table; je hebt dan een lookup in constante tijd in plaats van in lineaire tijd.
Jumptables (Beelzebubu haalt het ook reeds aan) zijn afaik alleen van toepassing bij kleine(re) contiguous blocks, omdat ze cache-optimalization en branch prediction graag vernueken. En op grotere switches zal een fatsoenlijke compiler exact dezelfde ASM generereren als voor een aantal if-jes.
curry684 probeert de boel nog een beetje te redden met een lookup in logaritmische tijd, maar om eerlijk te zijn betwijfel ik of die code daadwerkelijk efficienter is als je maar een stuk of 10 cases onderscheidt.
Met 10 cases is het inderdaad 4 tegen 10 lookups worst-case, en zal de overhead van de search en de functiecall het niet redden tegen een simpeler constructie, maar het ging hier geloof ik over 'enorm grote aantallen ranges' :)
Sowieso zou ik zelf omwille van de helderheid gewoon if-jes gebruiken, tenzij het zowel om veel ranges gaat en het case-statement van cruciaal belang is voor de performance van het geheel.
Eensch is :)

Professionele website nodig?


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

curry684

left part of the evil twins

Verwijderd schreef op 18 februari 2004 @ 16:09:
[...]
Overigens; hoe presteren de STL containers voor dit soort situaties?
Welke STL-container zou je hiervoor in willen zetten? :?

Enige wat ik me zo snel voor kan stellen is een map van integers naar functiepointers, en daar die intern als een binary tree is geimplementeerd zal ie niet efficienter zijn dan mijn routiner :)

Daarnaast staat er [C] in de topictitel en is dit dus wel een hele academische vraag ;)

Professionele website nodig?


  • Macros
  • Registratie: Februari 2000
  • Laatst online: 30-04 09:28

Macros

I'm watching...

Gcc expand range cases door het uit te schrijven.
case 1 ... 10:

wordt:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:

Gcc gebruikt een jump table om te springen naar het goede plekje. Daarbij is de table even groot als de totale range. Dus als je range tussen de 0 en de 683030 is, met vanalles er tussen, dan is de gcc manier erg slecht kwa geheugen gebruik, wat weer extra stress legt op je chaches. Zoals altijd is het een evenwicht dat je zoekt tussen snelheid en geheugen gebruik waarbij beide binnen goede ordes moeten liggen. N is de totale range, n zijn de hoeveelheid ranges. De gcc manier is O(N) kwa geheugen, O(1) kwa snelheid. If'jes zijn O(n) kwa snelheid en O(1) kwa ruimte. B-search is O(logN) op snelheid en O(1) op geheugen gebruik.

"Beauty is the ultimate defence against complexity." David Gelernter


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

curry684

left part of the evil twins

Macros schreef op 18 februari 2004 @ 16:28:
N is de totale range, n zijn de hoeveelheid ranges. De gcc manier is O(N) kwa geheugen, O(1) kwa snelheid. If'jes zijn O(n) kwa snelheid en O(1) kwa ruimte. B-search is O(logN) op snelheid en O(1) op geheugen gebruik.
B-search is O(n) op geheugengebruik, evenals de if-jes :)

Daarnaast is O(1) een misleidende term, de correcte is O(const), omdat de ene O(const) implementatie rustig 50 keer sneller kan zijn dan de andere O(const), wat je aan O(1) niet kunt zien :)

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:00

.oisyn

Moderator Devschuur®

Demotivational Speaker

curry684 schreef op 18 februari 2004 @ 16:22:
Jumptables (Beelzebubu haalt het ook reeds aan) zijn afaik alleen van toepassing bij kleine(re) contiguous blocks, omdat ze cache-optimalization en branch prediction graag vernueken.
Euh ja, en laten we het nu eens hebben over het traversen van een binary tree opgeslagen in een array, waarbij je steeds naar links moet :z ;)

(die lookup in de array is 1 cache-miss, de lookup in je binary tree zijn in dat geval 2log N cache misses)

Een binary heap is dan iig een betere datastructuur, waar de kinderen zich altijd op positie i*2 en i*2+1 bevinden (dan krijg je de cache miss effectief pas na 2log (32 / sizeof (int)) = 3 kinderen

[ Voor 17% gewijzigd door .oisyn op 18-02-2004 17:19 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

curry684 schreef op 18 februari 2004 @ 16:22:
Met 10 cases is het inderdaad 4 tegen 10 lookups worst-case, en zal de overhead van de search en de functiecall het niet redden tegen een simpeler constructie, maar het ging hier geloof ik over 'enorm grote aantallen ranges' :)
Hangt van je toepassing af. Voor media-dingen (die wil je echt puur op performance wil schrijven; uitleg doe je maar in specs of comments) wil ik dan best dit soort extensies gebruiken, ik roep deze functie misschien wel eenmaal per pixelkleur (rgb24) aan, is 720x576x25x3=33M/sec... Sure, dan wil ik die microseconde tijdswinst per cycle graag hebben!

En tuurlijk, in een simpel UI progje zal ik ook de if/else constructie gebruiken. :). Die ene microseconde, boeiuh...

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:00

.oisyn

Moderator Devschuur®

Demotivational Speaker

een switch bij het bepalen van een pixelkleur? :X ;)

[ Voor 3% gewijzigd door .oisyn op 18-02-2004 20:37 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1