Seite 1 von 1

Codeoptimierung

Verfasst: Mi Jun 17, 2009 6:42 pm
von sukka
Hi Leute,

ich brauche mal grad ein wenig Hilfe,

ich hab mir ne Funktion zum Rehashen geschrieben, bin mir allerdings nicht sicher, ob das die sinnvollste Implementierung ist, könnt ihr bitte mal drüberschauen ob euch noch was dazu einfällt das eleganter zu lösen?

Code: Alles auswählen

//Rehashing

#include <iostream>
#include <math.h>
#include <vector>
using namespace std;

void rehashing (vector<int> &);
int primzahl (int);
bool primzahl1 (int);


void main(void)
{
	vector <int> hashmap;
	hashmap.resize(8);
	hashmap[0]=16;
	hashmap[1]=9;
	hashmap[2]=0;
	hashmap[3]=19;
	hashmap[4]=32;
	hashmap[5]=21;
	hashmap[6]=5;
	hashmap[7]=0;

	rehashing(hashmap);
	for (unsigned int i = 0; i < hashmap.size(); i++)
		cout << i << "\t" << hashmap[i] << endl;

	return;
}

void rehashing (vector<int> &Hash)
{
	int M = Hash.size();
	int *speicher = new int[M];
	int Mnew = primzahl(M);
	bool eingefuegt = false;
	for (int i = 0; i < M; i++)
	{
		speicher[i]=Hash[i];
	}
	Hash.resize(Mnew);
	for (int i = 0; i < M; i++)
	{
		Hash[i]=0;
	}
	for (int i = 0; i < M; i++)
	{
		if (Hash[speicher[i]%Mnew]==0)
			Hash[speicher[i]%Mnew]=speicher[i];
		else
		{
			eingefuegt=false;
			int j = 1;
			do
			{
				if (Hash[speicher[i+j]%Mnew]==0)
				{
					Hash[speicher[i+j]%Mnew]=speicher[i];
					eingefuegt=true;
				}
				else
				{
					j++;
					eingefuegt=false;
				}
			}while(!eingefuegt);
		}
	}
}


int primzahl(int m)

{
	int erg;
	bool Primzahl=false;
	int j=1;
	do
	{
		if (primzahl1(m*2+j))
		{
			erg=m*2+j;
			Primzahl = true;
		}
		else
			j++;
	}while (!Primzahl);
	return erg;
}

bool primzahl1 (int m)
{
	for (int z = 2; z < m/2; z++)
	{
		if (m%z==0)
			return false;
	}
	return true;
}
Vielen Dank

Sukka

Re: Codeoptimierung

Verfasst: Mi Jun 17, 2009 7:21 pm
von Dirty Oerti
Hm, ich habe mal gehört (kann es also nicht bestätigen), dass es schneller sein soll, wenn man bei for die Abfrage dahingehend umstellt, dass geprüft wird, ob == 0.
Also anstatt von

Code: Alles auswählen

for (int i = 0; i < X; i++)
soll das hier verwendet werden:

Code: Alles auswählen

for (int i = X; i > 0; i--)
Ich weiß jetzt natürlich nicht, inwieweit das deine Anwendung zulässt...

Was du auch noch probieren könntest ist "loopunrolling", heißt weniger for-schleifen und mehr redundanten Code zu schreiben.
Geht aber leider nur in seltenen Fällen, und obs so viel bringt weiß ich auch nicht.

Re: Codeoptimierung

Verfasst: Mi Jun 17, 2009 7:29 pm
von sukka
Das mit dem Runterzählen würde mir an der Stelle nichts bringen, da ich dann nicht mehr Rehashen würde sondern die Reihenfolge durcheinanderwürfeln würde, wenn dann ginge das nur rekursiv und das ist deutlich Speicherfressender, deswegen möchte ich das eigentlich nicht machen. Die Redundanzvermeidung war eigentlich mein Gedanke, aber mir fällt da nix zu ein, deswegen frag ich ja euch ^^

Re: Codeoptimierung

Verfasst: Mi Jun 17, 2009 7:31 pm
von Dirty Oerti
Ok, erstmal ums klar zustellen:

Willst du es optimieren (=schneller machen) oder einen guten Stil schreiben?

Wenn du so eine for-Schleife nämlich etwas aufbiegen kannst, dann entfällt dir eine Vergleichsoperation (ist wenig, du wirst davon bei einem kleinem, kurzem Programm nichts merken)

Re: Codeoptimierung

Verfasst: Mi Jun 17, 2009 11:33 pm
von sukka
Sowohl als auch ;)

Re: Codeoptimierung

Verfasst: Do Jun 18, 2009 10:47 am
von Kerli
Dirty Oerti hat geschrieben:Was du auch noch probieren könntest ist "loopunrolling",
Also das würde ich im Normalfall doch eher dem Compiler überlassen. Weil wenn man das händisch macht schleichen sich erstens leichter Fehler ein und zweitens wird der Code dadurch nicht wirklich wartbarer. Mit dem gcc könntest du zb einmal -O3 versuchen, das sollte auch "loopunrolling" durchführen.
Minimal Zeit sparen könntest du auch mit der Verwendung vom Pre-Inkrement statt Post-Inkrement, auch wenn der Compiler das ev. eh sowieso optimiert.

Den Algorithmus kenne ich nicht, aber es wirkt ansich ganz ordentlich implementiert.

Ansonsten würde ich dir empfehlen Funktionen dannach zu benennen was sie genau tun bzw. der Code bei ihrer verwendung schon fast zu sinnvollen Satz(teilen) wird. zb:
- 'rehashing': rehash( hashmap) würde doch deutlich besser und flüssiger zu lesen sein, oder?
- 'primzahl'/'primzahl1': Was kann ich mir jetzt davon erwarten. Bekomme ich eine Primzahl oder kann ich überprüfen ob eine Zahl eine Primzahl ist. Da würde ich eher nextPrime oder isPrime nehmen.

Und weiters solltest du noch einen einheitlichen bzw. lesbareren Codingstandard einhalten:
- Variablen einheitlich benennen: Am Besten alles klein mit Underscores.
- einheitliche Sprache: Da Programmieren nun einmal auf Englisch abläuft würde sich da auch Englisch gut anbieten.
- Abstände zwischen Operatoren machen: "hashmap[0] = 16;" ist doch viel besser zu lesen als "hashmap[0]=16;" oder statt "if (Hash[speicher%Mnew]==0)" so schreibt: "if( Hash[ speicher % Mnew ] == 0 )"

Re: Codeoptimierung

Verfasst: Do Jun 18, 2009 11:12 am
von Jside
Dirty Oerti hat geschrieben:Hm, ich habe mal gehört (kann es also nicht bestätigen), dass es schneller sein soll, wenn man bei for die Abfrage dahingehend umstellt, dass geprüft wird, ob == 0.
Also anstatt von

Code: Alles auswählen

for (int i = 0; i < X; i++)
soll das hier verwendet werden:

Code: Alles auswählen

for (int i = X; i > 0; i--)
Also bei Binärer Subtraktion Invertiert der CPU vorher den B Operanden, und Addiert das ganze dann mit dem A Operanden, liegt nun daran, ob der CPU vor der ALU den Operanden direkt Invertieren kann, wenn nicht, ist dafuer ein weiterer Parcel nötig, ist aber auch von der Zykluszeit wegen dem Invertieren länger, als eine pure Addition, liegt aber an der Intelligenz des Compilers, und der ALU in der CPU...

Re: Codeoptimierung

Verfasst: Fr Jun 19, 2009 8:10 am
von sukka
Super, vielen Dank für die zahlreichen Antworten, das bringt mich auf jeden Fall erstmal weiter
das mit der Anpassung der Variablennamen, bzw der genaueren Bezeichnung ist ne gute Idee, sollte ich mir überlegen :)