Tag Archives: Speicher

C-Programm – Dynamische Speicherverwaltung

In diesem Beispiel zeigt ich, wie man Speicher dynamisch anlegen bzw. verwalten kann …

/*
============================================================================
Autor          : Lars Moelleken
Datum          : 10.02.2011
Beschreibung   : Preiskalkulation
Version        : 1.0
Compiler       : gcc 4.6.2-12
Programmschnittstelle: int main(void)
Das Programm gibt den Wert 0 oder 1 zurück.
Es werden keine Argumente erwartet.
============================================================================
*/

/*
============================================================================
Praeprozessoranweisungen
============================================================================
*/
#include 
#include 
#include 
#include 
#if defined __linux__
#include 
#elif defined _WIN32 || defined _WIN64
#define false 0
#define true 1
#endif

#define FUNSTAR_PREIS 1243.43
#define FUNSTAR_NAME "Fun Star"
#define HIGHEND_PREIS 1658.50
#define HIGHEND_NAME "High End"
#define MULTIMEDIASTAR_PREIS 698.20
#define MULTIMEDIASTAR_NAME "Multimedia Star"
#define OFFICESTAR_PREIS 1015.39
#define OFFICESTAR_NAME "Office Star"
#define GEHAEUSE_NAME "Gehaeuse"
#define LX100_PREIS 97.05
#define LX100_NAME "Compucase LX100 weiss"
#define LX120_PREIS 68.89
#define LX120_NAME "Compucase LX120 schwarz"
#define LX34A_PREIS 103.60
#define LX34A_NAME "Compucase LX34A weiss"
#define MAINBOARD_PREIS 193.03
#define MAINBOARD_NAME "Mainboard"
#define CPU_PREIS 334.65
#define CPU_NAME "CPU"
#define FESTPLATTEN_PREIS 130.95
#define FESTPLATTEN_NAME "Festplatte"
#define GRAFIKKARTEN_PREIS 319.13
#define GRAFIKKARTEN_NAME "Grafikkarte"

// die Struktur existiert nach der Deklaration als neuer Datentyp
// per typedef kann ein Synonym fuer die Strucktur erstellt werden 
typedef struct 
{
   char *pcKundenname, *pcProduktname;
   int iKundenNr, iProduktanzahl, iLieferung, iMontage;
   double dPreis;
} kunden;

/*
============================================================================
Funktionsprototypen
============================================================================
*/
// neuer Datentyp "kunden" wird hier direkt verwendent
kunden* datenEinlesen(kunden *s,int *iAnzahl, char *pcKundenname, 
   char *pcProduktname, int iKundenNr, int iProduktanzahl,
   int iLieferung,int iMontage,double dPreis);
int cls(void);
int new_fflush(void);
int InArray(int x, int iArray[], int iSize);
int loeschen(kunden *s, int *iAnzahl, int i);
double berechnungPreis(double dInputPreis, int iLieferung,
   int iMontage, int iAusgabe);
int ausgabeWarenkorb(kunden *s, int iAnzahl);
int ausgabeGesamtpreis(kunden *s, int iAnzahl);
int sucheNachKundenNr(kunden *s, int iAnzahl, int iKundenNr);
int sucheNachName(kunden *s, int iAnzahl, char *pcKundenname);
char *readKundenName(kunden *s, int iAnzahl, int iKundenNr);
int readProduktanzahl(void);
int readMontage(void);
int readLieferung(void);
int readKundenNr(void);
int printMenu(void);
int printMenuStandard(void);
int printMenuEinzel(void);
int printMenuGehaeuse(void);

/*
============================================================================
Funktion main() - Hauptfunktion
============================================================================
*/
int main(void)
/*
Rückgabewert:    0 ==> alles OK
                 1 ==> es ist ein Fehler aufgetreten
Es werden keine Argumente übergeben!
*/
{
   char cNamePuffer[100], cProduktPuffer[100], cInput;
   int iAnzahl=0, i, iKundenNr, inputStandard, auswahl, iProduktanzahl, 
      iShowMenu=true, iLieferung=false, iMontage=false;
   double dPreis;
 
   // Zeiger auf einen Eintrag definieren 
   kunden *s;
   // neuen Speicherbereich fuer die Struktur "kunden" anlegen
   s = (kunden*) malloc(sizeof(iAnzahl));
   // falls kein Speicherplatz zur Verfuegung steht ...
   if (s == NULL)
   {
      printf("Fehler: .......Speicherplatzmangel\n");
      exit(1);
   }
 
   // solange bis '0' eingegeben wird ...
   do 
   {
      if (iShowMenu == 1) 
      {
         cls();
         // Ausgabe vom Warenkorb
         ausgabeGesamtpreis(s,iAnzahl);
         // Ausgabe vom Menue
         printMenu();
      }  
      // Eingabe
      scanf("%c", &cInput);
      new_fflush();
      // Auswahl zur Eingabe 
      switch (cInput) 
      {
         // Einlesen
         case 'a': case 'A':
            iShowMenu=false;
            // i = 1 => true
            i = 1;
            // solange i = true ...
            while (i == true)
            {
               do
               {
                  cls();
                  // Ausgabe vom Warenkorb
                  ausgabeGesamtpreis(s,iAnzahl);
                  // Ausgabe vom MenueStadard
                  printMenuStandard();
                  scanf("%d", &inputStandard);
                  new_fflush();
               } 
               while (inputStandard != 0 && 
               		 inputStandard != 1 && 
               		 inputStandard != 2 && 
               		 inputStandard != 3 && 
               		 inputStandard != 4);
               // Auswahl zur Eingabe 
               switch (inputStandard) 
               {
                  case 1:
                     dPreis=FUNSTAR_PREIS;
                     strncpy(cProduktPuffer,FUNSTAR_NAME,
                     		 strlen(FUNSTAR_NAME) +1);
                     break;
                  case 2:
                     dPreis=HIGHEND_PREIS;
                     strncpy(cProduktPuffer,HIGHEND_NAME,
                     		 strlen(HIGHEND_NAME) +1);
                     break;
                  case 3:
                     dPreis=MULTIMEDIASTAR_PREIS;
                     strncpy(cProduktPuffer,MULTIMEDIASTAR_NAME,
                     		 strlen(MULTIMEDIASTAR_NAME) +1);
                     break;
                  case 4:
                     dPreis=OFFICESTAR_PREIS;
                     strncpy(cProduktPuffer,OFFICESTAR_NAME,
                     		 strlen(OFFICESTAR_NAME) +1);
                     break;
                  default:
                     dPreis=0;
                     // i = 0 => false => while-Schleife wird verlassen
                     i=false;
                     cls();
                     iShowMenu=true;
                     break;
               }
               if (dPreis != 0)
               {
                  iKundenNr=readKundenNr();
                  strcpy(cNamePuffer,readKundenName(s, iAnzahl, iKundenNr));
                  iProduktanzahl=readProduktanzahl();
                  iLieferung=readLieferung();

                  cls();
                  berechnungPreis(dPreis, iLieferung, iMontage, 1);

                  printf("\n\nIn den Warenkorb? ('j' fuer ja) ");
                  // Einlesen von cInput
                  scanf("%c", &cInput);
                  new_fflush();
                  printf("\n\n");
                  // wenn Eingabe ungleich j ist, dann ...
                  if (cInput == 'j') 
                  {
                     // Speicher wird per Funktion (datenEinlesen) erstellt
                     s = datenEinlesen(s,&iAnzahl,cNamePuffer,cProduktPuffer,
                     		 iKundenNr,iProduktanzahl,iLieferung,iMontage,dPreis);

                     printf("\n**Eintrag gespeichert**\n");
                     printf("\n\tweiteren Eintrag anlegen? ('j' fuer ja) ");
                  }
                  else
                  {
                     printf("\n\tanderen Eintrag anlegen? ('j' fuer ja) ");
                  }

                  // Einlesen von cInput
                  scanf("%c", &cInput);
                  new_fflush();
                  printf("\n\n");
                  // wenn Eingabe ungleich j ist, dann ...
                  if (cInput != 'j') 
                  {
                     // i = 0 => false => while-Schleife wird verlassen
                     i=false;
                     cls();
                     iShowMenu=true;
                  }
                  else
                  {
                     cls();
                     iShowMenu=false;
                  }
               }
            }
            // beendet eine Schleife bzw. eine case-Anweisung 
            break;
         // Einlesen
         case 'b': case 'B':
            cls();
            iShowMenu=false;
            // i = 1 => true
            i = true;
            // solange i==true ...
            while (i == true)
            {
               do
               {
                  cls();
                  // Ausgabe vom Warenkorb
                  ausgabeGesamtpreis(s,iAnzahl);
                  // Ausgabe vom MenueStadard
                  printMenuEinzel();
                  scanf("%d", &inputStandard);
                  new_fflush();
               } 
               while (inputStandard != 0 && 
               		 inputStandard != 1 && 
               		 inputStandard != 2 && 
               		 inputStandard != 3 && 
               		 inputStandard != 4 && 
               		 inputStandard != 5);
               // Auswahl zur Eingabe 
               switch (inputStandard) 
               {
                  case 1:
                     // i = 0 => false => while-Schleife wird verlassen
                     i=false;
                     do
                     {
                        cls();
                        // Ausgabe vom Warenkorb
                        ausgabeGesamtpreis(s,iAnzahl);
                        // Ausgabe vom MenueStadard
                        printMenuGehaeuse();
                        scanf("%d", &inputStandard);
                        new_fflush();
                     } 
                     while (inputStandard != 0 && 
                     		 inputStandard != 1 && 
                     		 inputStandard != 2 && 
                     		 inputStandard != 3);
                     // Auswahl zur Eingabe 
                     switch (inputStandard)
                     {
                        case 1:
                           dPreis=LX100_PREIS;
                           strncpy(cProduktPuffer,LX100_NAME,
                           		 strlen(LX100_NAME) +1);
                           break;
                        case 2:
                           dPreis=LX120_PREIS;
                           strncpy(cProduktPuffer,LX120_NAME,
                           		 strlen(LX120_NAME) +1);
                           break;
                        case 3:
                           dPreis=LX34A_PREIS;
                           strncpy(cProduktPuffer,LX34A_NAME,
                           		 strlen(LX34A_NAME) +1);
                           break;
                        default:
                           dPreis=0;
                           // i = 0 => false => while-Schleife wird verlassen
                           i=false;
                           cls();
                           iShowMenu=true;
                           break;
                     }
                     break;
                  case 2:
                     dPreis=MAINBOARD_PREIS;
                     strncpy(cProduktPuffer,MAINBOARD_NAME,
                     		 strlen(MAINBOARD_NAME) +1);
                     break;
                  case 3:
                     dPreis=CPU_PREIS;
                     strncpy(cProduktPuffer,CPU_NAME,
                     		 strlen(CPU_NAME) +1);
                     break;
                  case 4:
                     dPreis=FESTPLATTEN_PREIS;
                     strncpy(cProduktPuffer,FESTPLATTEN_NAME,
                     		 strlen(FESTPLATTEN_NAME) +1);
                     break;
                  case 5:
                     dPreis=GRAFIKKARTEN_PREIS;
                     strncpy(cProduktPuffer,GRAFIKKARTEN_NAME,
                     		 strlen(GRAFIKKARTEN_NAME) +1);
                     break;
                  default:
                     dPreis=0;
                     // i = 0 => false => while-Schleife wird verlassen
                     i=false;
                     cls();
                     iShowMenu=true;
                     break;
               }
               if (dPreis != 0)
               {
                  iKundenNr=readKundenNr();
                  strcpy(cNamePuffer,readKundenName(s, iAnzahl, iKundenNr));
                  iProduktanzahl=readProduktanzahl();
                  iLieferung=readLieferung();
                  iMontage=readMontage();
 
                  cls();
                  berechnungPreis(dPreis, iLieferung, iMontage, 1);

                  printf("\n\nIn den Warenkorb? ('j' fuer ja) ");
                  // Einlesen von cInput
                  scanf("%c", &cInput);
                  new_fflush();
                  printf("\n\n");
                  // wenn Eingabe ungleich j ist, dann ...
                  if (cInput == 'j') 
                  {
                     // Speicher wird per Funktion (datenEinlesen) erstellt
                     s = datenEinlesen(s,&iAnzahl,cNamePuffer,cProduktPuffer,
                     		 iKundenNr,iProduktanzahl,iLieferung,iMontage,dPreis);

                     printf("\n**Eintrag gespeichert**\n");
                     printf("\n\tweiteren Eintrag anlegen? ('j' fuer ja) ");
                  }
                  else
                  {
                     printf("\n\tanderen Eintrag anlegen? ('j' fuer ja) ");
                  }

                  // Einlesen von cInput
                  scanf("%c", &cInput);
                  new_fflush();
                  printf("\n\n");

                  // wenn Eingabe ungleich j ist, dann ...
                  if (cInput != 'j') 
                  {
                     // i = 0 => false => while-Schleife wird verlassen
                     i=false;
                     cls();
                     iShowMenu=true;
                  }
                  else
                  {
                     cls();
                     iShowMenu=false;
                  }
               }
            }
            // beendet eine Schleife bzw. eine case-Anweisung 
            break;
         // Ausgabe
          case 'c': case 'C':
            cls();
            iShowMenu=false;
            // wenn Anzahl gleich 0, dann ...
            if (iAnzahl==0) 
            {
               printf("\n\n**Kein Eintrag gefunden**\n\n");
            } 
            else 
            {
               ausgabeWarenkorb(s,iAnzahl);
            }
            printf("\ndrueke 'Enter' um fortzufahren: ...\n");
            if (getchar() == '\n')
            {
               cls();
               iShowMenu=true;
            }
            // beendet eine Schleife bzw. eine case-Anweisung 
            break;
         // Nach Kunden-Namen suchen
         case 'd': case 'D':
            cls();
            iShowMenu=false;
            printf("Suchen (Kunden-Name): ");
            // Einlesen von cNamePuffer (pcKundenname)
            scanf("%99s", cNamePuffer);
            new_fflush();
            // Funktion wird aufgerufen 
            sucheNachName(s,iAnzahl,cNamePuffer);
            printf("\ndrueke 'Enter' um fortzufahren: ...\n");
            if (getchar() == '\n')
            {
               cls();
               iShowMenu=true;
            }
            // beendet eine Schleife bzw. eine case-Anweisung 
            break;
         // Nach Kunden-Nr. suchen
         case 'e': case 'E':
            cls();
            iShowMenu=false;
            printf("Suchen (Kunden-Nr.): ");
            // Einlesen von iKundenNr
            scanf("%d",&iKundenNr);
            new_fflush();
            // Funktion wird aufgerufen 
            sucheNachKundenNr(s,iAnzahl,iKundenNr);
            printf("\ndrueke 'Enter' um fortzufahren: ... \n");
            if (getchar() == '\n')
            {
               cls();
               iShowMenu=true;
            }
            // beendet eine Schleife bzw. eine case-Anweisung 
            break;
         // Einen Eintrag löschen
         case 'f': case 'F':
            cls();
            iShowMenu=false;
            printf("Loeschen: ");
            i=true;
            while (i == true) 
            {
               if (iAnzahl != 0) 
               {
                  for (i=0; i != iAnzahl; i++) 
                  {
                     printf("\n\t---------------------------------------");
                     printf("\n\tIndex: %d -> Kunde: %s (%d)", i, 
                     		 s[i].pcKundenname, s[i].iKundenNr);
                     printf("\n\t---------------------------------------");
                  }
                  printf("\n\nIndex angeben: ");
                  scanf("%d",&auswahl);
                  new_fflush();
                  if (auswahl < 0 || auswahl >= iAnzahl) 
                  {
                     cls();
                     printf("\nungueltige Eingabe\n\n");
                  } 
                  else 
                  {
                     printf("\n\tEintrag wirklich loeschen? ('j' fuer ja) ");
                     // Einlesen von cInput
                     scanf("%c", &cInput);
                     new_fflush();
                     printf("\n\n");

                     // wenn Eingabe gleich j ist, dann ...
                     if (cInput == 'j') 
                     {
                        loeschen(s,&iAnzahl,auswahl);
                        i=false;
                           printf("\n\n**Eintrag geloescht !**\n\n");
                     }
                     else
                     {
                        // i = 0 => false => while-Schleife wird verlassen
                        i=false;
                        iShowMenu=true;
                     }

                  }
               } 
               else 
               {
                  i=false;
                  printf("\n\n**Kein Eintrag gefunden**\n\n");
               }
               printf("\ndrueke 'Enter' um fortzufahren: ... \n");
               if (getchar() == '\n')
               {
                  cls();
                  iShowMenu=true;
               }
            }
            // beendet eine Schleife bzw. eine case-Anweisung 
            break;
         // Speicher wieder freigeben (free)
         case 'x': case 'X':
            for (i=0; i != iAnzahl; i++) 
            {
               // "free" gibt den Speicher wieder frei
               free(s[i].pcKundenname);
            }
            // testing
            //free(s);
            // Alternative schreibweise:
            // realloc(s,0);
            // beendet eine Schleife bzw. eine case-Anweisung
            break;
         // Standard 
         default:
            iShowMenu=true;
            break;
      }
   // solange in der Schleife bleiben, bis 0 eingegeben wird 
   } 
   while (cInput != 'x' && cInput != 'X');
 
   return 0;
}

/*
============================================================================
Funktion datenEinlesen() - der Speicher wird bereitgestellt und die Eingaben 
               an die Strucktur uebergeben
============================================================================
*/
kunden* datenEinlesen(kunden *s, int *iAnzahl, char *pcKundenname,
   char *pcProduktname, int iKundenNr, int iProduktanzahl,
   int iLieferung, int iMontage, double dPreis)
/*
Rückgabewert:    s ==> neuen Speicherbereich
Argumente:    *s ==> Zeiger auf den neuen Speicherbereich
      *iAnzahl ==> Zeiger auf die Anzahl an Eintraegen
      *pcKundenname ==> Zeiger auf den Kunden-Namen
      *pcProduktname ==> Zeiger auf den Produkt-Namen 
      iKundenNr ==> Kunden-Nr.
      iProduktanzahl ==> Anzahl vom bestellten Produkten
      iLieferung ==> Lieferung (1=ja || 0=nein)
      iMontage ==> Montage (1=ja || 0=nein)
      dPreis ==> Preis pro Produkt
*/
{
   //
   // realloc() -    kann Speicherplatz von einem bereits zugeteilten 
   //      Blocks vergroeßern oder verkleinern, dazu wird ein 
   //      Zeiger auf die Anfangsadresse des neu reservierten 
   //      Speicherblocks gesetzt, dabei bleibt der Inhalt des 
   //      urspruenglichen Speicherblocks erhalten und der neue 
   //      Speicherblock wird hinten angefuegt
   //
   // Speicherbereich wird vergroeßert
   s=(kunden*)realloc(s,sizeof(kunden)*(*iAnzahl +1));
   //
   // strlen -    gibt die Anzahl der Zeichen eines Strings 
   //      ohne das Null-Zeichen zurueck
   // strcpy -    Stringfunktion zum kopieren einer Zeichenkette       
   //
   // malloc() -    reserviert genau so viel zusammenhaengenden Speicher, 
   //      wie angegeben wird, zurueckgegeben wird ein typenloser 
   //      Zeiger auf void mit der Anfangsadresse des 
   //      Speicherbereichs
   //
   // z.B.: 
   // Speicher fuer 100 int-Elemente reservieren 
   // ptr = malloc(100 * sizeof(int));
   // ...
   // Speicher auf 50 int-Elemente verkleinern 
   // ptr = realloc(ptr, 50 * sizeof(int));
   // ...
   // Speicher von 256 auf 512 int-Elemente vergroeßern 
   // int block = 256;
   // ptr = malloc(block * sizeof(int));
   // block += block;
   // ptr = reallloc(ptr, block * sizeof(int));
   //
   // neuen Speicherbereich fuer einen neuen Namen anlegen
   // +1 wegen \0 -> am Ende vom String
   s[*iAnzahl].pcKundenname=(char*) malloc(strlen(pcKundenname) +1); 
   // falls kein Speicherplatz zur Verfuegung steht ...
   if (s[*iAnzahl].pcKundenname == NULL) 
   {
      printf("Fehler: .......Speicherplatzmangel\n");
      exit(1);
   }
   // der Strucktur (kunden) wird die Variable "pcKundenname" hinzugefuegt 
   strncpy(s[*iAnzahl].pcKundenname,pcKundenname,strlen(pcKundenname) +1);
   // der Strucktur (kunden) wird die Variable "iKundenNr" hinzugefuegt
   s[*iAnzahl].iKundenNr=iKundenNr;
   // neuen Speicherbereich fuer einen neuen Produktnamen anlegen
   // +1 wegen \0 -> am Ende vom String
   s[*iAnzahl].pcProduktname=(char*) malloc(strlen(pcProduktname) +1);
   // falls kein Speicherplatz zur Verfuegung steht ...
   if (s[*iAnzahl].pcProduktname == NULL) 
   {
      printf("Fehler: .......Speicherplatzmangel\n");
      exit(1);
   }
   // der Strucktur (kunden) wird die Variable "pcProduktname" hinzugefuegt 
   strncpy(s[*iAnzahl].pcProduktname,pcProduktname,strlen(pcProduktname) +1);
   // der Strucktur (kunden) wird die Variable "iProduktanzahl" hinzugefuegt   
   s[*iAnzahl].iProduktanzahl=iProduktanzahl; 
   // der Strucktur (kunden) wird die Variable "iLieferung" hinzugefuegt   
   s[*iAnzahl].iLieferung=iLieferung;
   // der Strucktur (kunden) wird die Variable "iMontage" hinzugefuegt   
   s[*iAnzahl].iMontage=iMontage;
   // der Strucktur (kunden) wird die Variable "dPreis" hinzugefuegt 
   s[*iAnzahl].dPreis=dPreis;
   // die Anzahl der Kunden um 1 erhoehen
   ++*iAnzahl;
   return s;
}

/*
============================================================================
Funktion cls() - clear
============================================================================
*/
int cls(void)
/*
Rückgabewert:    0 ==> alles OK
Es werden keine Argumente übergeben!
*/
{
#if defined __linux__
   printf("\033[2J");
#elif defined _WIN32 || defined _WIN64
   system("cls");
#endif
   return 0;
}

/*
============================================================================
Funktion new_fflush() - fflush(stdin) for Linux and Windows
============================================================================
*/
int new_fflush(void)
/*
Rückgabewert:    0 ==> alles OK
Es werden keine Argumente übergeben!
*/
{
#if defined __linux__
   int ch;
   while ((ch = getchar()) != '\n' && ch != EOF);                  
#elif defined _WIN32 || defined _WIN64
   fflush(stdin);
#endif
   return 0; 
}

/*
============================================================================
Funktion InArray() - check if 'x' in the 'iArray'
============================================================================
*/
int InArray(int x, int iArray[], int iSize)
/*
Rückgabewert:    inArray ==> is in Array or not ;)
Argumente:   x ==> checking 'x'
      iArray[] ==> in this iArray
      iSize ==> iSize of the iArray
*/
{
   // default is "false"
   int inArray=false;
   int i;
   for (i=0; i alles OK
Argumente:   *s ==> Zeiger auf den neuen Speicherbereich
      *iAnzahl ==> Zeiger auf die Anzahl an Eintraegen
      i ==> Auswahl des Indexes 
*/
{
   // solange Index nicht Anzahl ist ...
   for (i; i != *iAnzahl; i++) 
   {
      // Strucktur-Eintraege um 1 erhoehen
      s[i].pcKundenname=s[i+1].pcKundenname;
      s[i].iKundenNr=s[i+1].iKundenNr;
      s[i].pcProduktname=s[i+1].pcProduktname;
      s[i].iProduktanzahl=s[i+1].iProduktanzahl;
      s[i].iLieferung=s[i+1].iLieferung;
      s[i].iMontage=s[i+1].iMontage;
      s[i].dPreis=s[i+1].dPreis;
   }
   // Anzahl -1 
   --*iAnzahl;
   // Speicherbereich wird verkleinert
   s=(kunden*) realloc(s,sizeof(kunden) * (*iAnzahl));
   return 0;
}

// Funktion: berechnungPreis
double berechnungPreis(double dInputPreis, int iLieferung,
		int iMontage, int iAusgabe)
{
   // Ausgabe ...
   if (iAusgabe == 1) 
   {
      printf("\n\n\tListenpreis pro Artikel:\t%7.2lf", dInputPreis);
      printf("\n\t\t+ Lagerkosten:\t\t%7.2lf", dInputPreis * 0.1);
   }
   dInputPreis = dInputPreis + (dInputPreis  * 0.1);
   if (iAusgabe == 1) 
   {
      printf("\n\t---------------------------------------");
      printf("\n\tMaterialkosten:\t\t\t%7.2lf", dInputPreis);
      printf("\n\t\t+ Verwaltungskosten:\t%7.2lf", dInputPreis * 0.1);
   }
   dInputPreis = dInputPreis + (dInputPreis * 0.1);
   if (iAusgabe == 1) 
   {
      printf("\n\t---------------------------------------");
      printf("\n\tSelbstkosten:\t\t\t%7.2lf", dInputPreis);
      printf("\n\t\t+ Gewinn:\t\t%7.2lf", dInputPreis * 0.1);
   }
   dInputPreis = dInputPreis + (dInputPreis * 0.1);
   if (iAusgabe == 1) 
   {
      printf("\n\t---------------------------------------");
      printf("\n\tBarverkaufspreis:\t\t%7.2lf", dInputPreis);
   }
   if (iLieferung == 1)
   {
      if (iAusgabe == 1) 
      {
         printf("\n\t\t+ Versand:\t\t%7.2lf", dInputPreis * 0.05);
      }
      dInputPreis = dInputPreis + (dInputPreis * 0.05);
      if (iAusgabe == 1) 
      {
         printf("\n\t---------------------------------------");
         printf("\n\tVersandpreis:\t\t\t%7.2lf", dInputPreis);
      }
   }
   if (iMontage == 1)
   {
      if (iAusgabe == 1) 
      {
         printf("\n\t\t+ Montage:\t\t%.2lf", dInputPreis * 0.15);
      }
      dInputPreis = dInputPreis + (dInputPreis * 0.15);
      if (iAusgabe == 1) 
      {
         printf("\n\t---------------------------------------");
         printf("\n\tHerstellungskosten:\t\t%7.2lf", dInputPreis);
      }
   }
   return dInputPreis;
}

/*
============================================================================
Funktion ausgabeWarenkorb() - Warenkorb ausgeben
============================================================================
*/
int ausgabeWarenkorb(kunden *s, int iAnzahl) 
/*
Rückgabewert:    0 ==> alles OK
Argumente:   *s ==> Zeiger auf den neuen Speicherbereich
      iAnzahl ==> Anzahl an Eintraegen
*/
{
   int i, iArray[100];
   double gesamtpreis[100], dPreis[100];
   printf("\nWarenkorb (Einzelpreise):\n");
   // von 0 bis Anzahl ...
   for (i=0; i alles OK
Argumente:   *s ==> Zeiger auf den neuen Speicherbereich
      iAnzahl ==> Anzahl an Eintraegen
*/
{
   int i;
   double gesamtpreis=0, dPreis[32];
   // von 0 bis Anzahl ...
   for (i=0; i alles OK
      1 ==> es ist ein Fehler aufgetreten
Argumente:   *s ==> Zeiger auf den neuen Speicherbereich
      iAnzahl ==> Anzahl an Eintraegen
      iKundenNr ==> Kunden-Nr.
*/
{
   int i,x=false;
   double dPreis[100];
   // von 0 bis Anzahl ...
   for (i=0;i != iAnzahl; i++) 
   {
      // wenn der Eintrag gleich dem Suchbegriff ist ...
      if (s[i].iKundenNr==iKundenNr) 
      {
         dPreis[i] = berechnungPreis(s[i].dPreis, s[i].iLieferung,
         		 s[i].iMontage, 0);
         dPreis[i] = dPreis[i] * s[i].iProduktanzahl;
         printf("\n(Index: %3d)\nKunde: %s\nKunden-Nr: %d\nProdukt: %s\n"
         		 "Preis: %.2lf\n\n",i,s[i].pcKundenname,s[i].iKundenNr,
         		 s[i].pcProduktname,dPreis[i]);
         // x=1 -> Eintrag gefunden
         x=true;
      }
   }
   // wenn Eintrag nicht gefunden wurde, dann ...
   if (x==false) 
   {
      printf("\n\n**Kein Eintrag gefunden**\n\n");
      return 1;
   }
   else
   {
      return 0;
   }
}

/*
============================================================================
Funktion sucheNachName() - Infos ueber eine bestimmten Kunden-Namen
============================================================================
*/
int sucheNachName(kunden *s, int iAnzahl, char *pcKundenname)
/*
Rückgabewert:    0 ==> alles OK
      1 ==> es ist ein Fehler aufgetreten
Argumente:   *s ==> Zeiger auf den neuen Speicherbereich
      iAnzahl ==> Anzahl an Eintraegen
      *pcKundenname ==> Kunden-Name
*/
{
   int i,x=false;
   double dPreis[100];
   // von 0 bis Anzahl ...
   for (i=0;i != iAnzahl;i++) 
   {
      // Vergleich (strcmp) von char-Arrays bzw. String
      if ( !strcmp(pcKundenname,s[i].pcKundenname) ) 
      {
         dPreis[i] = berechnungPreis(s[i].dPreis, s[i].iLieferung,
         		 s[i].iMontage, 0);
         printf("\n(Index: %3d)\nKunde: %s\nKunden-Nr: %d\nProdukt: %s\n"
         		 "Preis: %.2lf\n\n",i,s[i].pcKundenname,s[i].iKundenNr,
         		 s[i].pcProduktname,dPreis[i]);
         // x=1 -> Eintrag gefunden
         x=true;
      }
   }
   // wenn Eintrag nicht gefunden wurde, dann ...
   if (x==false) 
   {
      printf("\n\n**Kein Eintrag gefunden**\n\n");
      return 1;
   }
   else
   {
      return 0;
   }
}

/*
============================================================================
Funktion readKundenName() - scanf with check
============================================================================
*/
char *readKundenName(kunden *s, int iAnzahl, int iKundenNr)
/*
Rückgabewert:    cNamePuffer ==> Kunden-Name
Argumente:   *s ==> Zeiger auf den neuen Speicherbereich
      iAnzahl ==> Anzahl an Eintraegen
      iKundenNr ==> Kunden-Nr.
*/
{
   int check=true, i;
   static char cNamePuffer[100];
   if (iAnzahl != 0) 
   {
      for (i=0; i != iAnzahl; i++) 
      {
         if (s[i].iKundenNr == iKundenNr)
         {
            strncpy(cNamePuffer,s[i].pcKundenname,
            		strlen(s[i].pcKundenname) +1);
            check=false;
         }
      }
   }
   if (check==true)
   {
      do 
      {
         printf("\tKunde (Name): ");
         // Einlesen von cNamePuffer (pcKundenname)
         scanf("%99s", cNamePuffer);
         new_fflush();
         if (!isalpha(cNamePuffer[0]))
         {
            printf("\n\n**Bitte einen korrekten Namen eingeben!!!**\n\n");
         }
      } 
      while (!isalpha(cNamePuffer[0]));
   }
   return cNamePuffer;
}

/*
============================================================================
Funktion readProduktanzahl() - scanf with check
============================================================================
*/
int readProduktanzahl(void)
/*
Rückgabewert:    iProduktanzahl ==> Produktanzahl
Es werden keine Argumente übergeben!
*/
{
   int check=true, iProduktanzahl;
   check=true;
   do 
   {
      printf("\tAnzahl: ");
      // Einlesen der Produktanzahl
      check = !scanf("%d", &iProduktanzahl);
      new_fflush();
      if (check)
      {
         printf("\n\n**Bitte eine korrekte Produktanzahl eingeben!!!**\n\n");
      }
   } 
   while (check);
   return iProduktanzahl;
}

/*
============================================================================
Funktion readLieferung() - scanf with check
============================================================================
*/
int readMontage(void)
/*
Rückgabewert:    iMontage ==> Montage (1 | 0)
Es werden keine Argumente übergeben!
*/
{
   int iMontage=0;
   char cInput;
   do 
   {
      printf("\tMontage: ('j' fuer ja) ");
      // Einlesen der Montage
      scanf("%c", &cInput);
      new_fflush();
      if (!isalpha(cInput))
      {
         printf("\n**Bitte eine korrekte Eingabe taetigen!!!**\n");
      }
   } 
   while (!isalpha(cInput));
   if (cInput == 'j') 
   {
      iMontage=true;
   }
   return iMontage;
}

/*
============================================================================
Funktion readLieferung() - scanf with check
============================================================================
*/
int readLieferung(void)
/*
Rückgabewert:    iLieferung ==> Lieferung (1 | 0)
Es werden keine Argumente übergeben!
*/
{
   int iLieferung=0;
   char cInput;   
   do 
   {
      printf("\tLieferung: ('j' fuer ja) ");
      // Einlesen der Lieferung
      scanf("%c", &cInput);
      new_fflush();
      if (!isalpha(cInput))
      {
         printf("\n\n**Bitte eine korrekte Eingabe taetigen!!!**\n\n");
      }
   } 
   while (!isalpha(cInput));
   if (cInput == 'j') 
   {
      iLieferung=true;
   }
   return iLieferung;
}

/*
============================================================================
Funktion readKundenNr() - scanf with check
============================================================================
*/
int readKundenNr(void)
/*
Rückgabewert:    iKundenNr ==> Kunden-Nr.
Es werden keine Argumente übergeben!
*/
{
   int check=true, iKundenNr;
   do 
   {
      printf("\n\tKunden-Nr.: ");
      // Einlesen der iKundenNr
      check = !scanf("%d", &iKundenNr);
      new_fflush();
      if (check)
      {
         printf("\n\n**Bitte eine korrekte Kunden-Nr. eingeben!!!**\n\n");
      }
   } 
   while (check);
   return iKundenNr;
}

/*
============================================================================
Funktion printMenu() - Ausgabe vom Menue
============================================================================
*/
int printMenu(void) 
/*
Rückgabewert:    0 ==> alles OK
Es werden keine Argumente übergeben!
*/
{
   printf("\n\tP R E I S K A L K U L A T I O N");
   printf("\n\t===============================");
   printf("\n\n\ta: Standardkonfiguration");
   printf("\n\n\tb: Einzelkomponenten");
   printf("\n\n\tc: Warenkorb anzeigen"); 
   printf("\n\n\td: Suchen (Kunden-Name)");
   printf("\n\n\te: Suchen (Kunden-Nr.)");
   printf("\n\n\tf: Loeschen");
   printf("\n\n\tx: Ende");
   printf("\n\n\n\tAuswahl: ");
   return 0;
}

/*
============================================================================
Funktion printMenuStandard() - Ausgabe vom Standard-Menue
============================================================================
*/
int printMenuStandard(void) 
/*
Rückgabewert:    0 ==> alles OK
Es werden keine Argumente übergeben!
*/
{
   printf("\n\tS T A N D A R D K O N F I G U R A T I O N");
   printf("\n\t=========================================");
   printf("\n\n\t1: %s\t\t%5.2f", FUNSTAR_NAME, FUNSTAR_PREIS);
   printf("\n\t2: %s\t\t%5.2f", HIGHEND_NAME, HIGHEND_PREIS);
   printf("\n\t3: %s\t% 5.2f", MULTIMEDIASTAR_NAME, MULTIMEDIASTAR_PREIS);
   printf("\n\t4: %s\t\t%5.2f", OFFICESTAR_NAME, OFFICESTAR_PREIS);
   printf("\n\t0: Abbruch");
   printf("\n\n\n\tAuswahl: ");
   return 0;
}

/*
============================================================================
Funktion printMenuEinzel() - Ausgabe vom Einzel-Menue
============================================================================
*/
int printMenuEinzel(void) 
/*
Rückgabewert:    0 ==> alles OK
Es werden keine Argumente übergeben!
*/
{
   printf("\n\tE I N Z E L K O M P O N E N T E N");
   printf("\n\t=================================");
   printf("\n\n\t1: %s", GEHAEUSE_NAME);
   printf("\n\t2: %s\t\t%5.2f", MAINBOARD_NAME, MAINBOARD_PREIS);
   printf("\n\t3: %s\t\t\t%5.2f", CPU_NAME, CPU_PREIS);
   printf("\n\t4: %s\t\t%5.2f", FESTPLATTEN_NAME, FESTPLATTEN_PREIS);
   printf("\n\t5: %s\t\t%5.2f", GRAFIKKARTEN_NAME, GRAFIKKARTEN_PREIS);
   printf("\n\t0: Abbruch");
   printf("\n\n\n\tAuswahl: ");
   return 0;
}

/*
============================================================================
Funktion printMenuEinzel() - Ausgabe vom Einzel-Menue
============================================================================
*/
int printMenuGehaeuse(void) 
/*
Rückgabewert:    0 ==> alles OK
Es werden keine Argumente übergeben!
*/
{
   printf("\n\tG E H A E U S E K O M P O N E N T E N");
   printf("\n\t=====================================");
   printf("\n\n\t1: %s\t %5.2f", LX100_NAME, LX100_PREIS);
   printf("\n\t2: %s\t %5.2f", LX120_NAME, LX120_PREIS);
   printf("\n\t3: %s\t%5.2f", LX34A_NAME, LX34A_PREIS);
   printf("\n\t0: Abbruch");
   printf("\n\n\n\tAuswahl: ");
   return 0;
}
7_9139598_Cool_Tacho_256x256_main_-192x192_

SpeedUp Ubuntu

1.) Kenne dein System (Hardware)

Am besten ist es den Flaschenhals an seinem System ausfindig zu machen, dafür sollte man wissen wie viel Arbeitsspeicher zur Verfügung steht, CPU Auslastung, Festplattengeschwindigkeit etc. aktuell verbraucht wird. Ggf. kann man auch mit neuer Hardware (z.B. > RAM) das System beschleunigen, dies muss natürlich bei jedem System einzeln geprüft werden.


1.1) Arbeitsspeicher


free -mt


  • total: kompletter physikalischer Speicher ( – ein wenig für den Kernel)
  • use: verwendeter Speicher
  • free: freier Speicher
  • buffers/cache: Speicher der wieder freigegeben werden kann, wenn dieser benötig wird. (Cache)

Somit sollte auch klar sein, dass es GUT ist, wenn der Arbeitsspeicher gut ausgenutzt wird, sollte jedoch “use” – “buffer/cache” zu klein werden oder bereits “Swap” (Auslagerungsspeicher -> meist Festplattenplatz) verbracht wird und somit das System wirklich ausbremst.


1.2) Festplatte


hdparm -t /dev/harddrive


Wenn es ewig dauert bis das System gebootet ist oder Programme starten, sollte man die Lesegeschwindigkeit seiner Festplatte einmal testen und ggf. eine neue Festplatte kaufen. ;-) Dabei sollte die Festplatte nicht unter ~50MB/s sein. Moderne SATA-Festplatten haben im Durchschnitt 100MB/s und bei SSD-Festplatten ist eine Datenraten bis zu ~500 MB/s möglich. (SATA-600).


1.3) CPU


top


Ich hatte das Programm “top” bereits in einem vorherigen Blog-Post beschrieben -> http://suckup.de/blog/2010/11/09/linux-server-analysieren/ <- top zeigt unter anderem die Auslastung der CPU je Programm an.


1.4) Grafikkarte


glxinfo | grep direct


Wenn du Engpässe beim abspielen von Videos oder beim Spielen feststellst, kannst du mit dem vorherigem Befehl feststellen, ob “Direct Rendering” aktiviert ist. Ggf. reicht es aus andere Treiber zu installieren, nach meiner Erfahrung sind die Proprietäten Treiber bei neuen Grafikkarten (ATI & NVIDIA) sehr gut. (http://suckup.de/blog/2010/02/09/lxde-compiz-emerald-awn-ubuntu-howto/) Wer eine alte Grafikkarte hat, kann auch diese 3D-Effekte (Compiz) ausschalten, ggf. andere Treiber installieren und schauen, ob der Desktop dadruch flüssiger läuft.


2.) Lightweight Software

Bevor man in neue Hardware investiert (oder sich diese zu Weihnachten schenken lässt) sollte man einmal “Lightweight Software” ausprobieren, diese bieten zwar ggf. weniger Funktionen, sind dafür aber schneller.


z.B.:
Desktop: Gnome -> LXDE oder Xfce
Browser: Firefox -> Chromium


https://wiki.archlinux.org/index.php/Lightweight_Applications


3.) Speicherplatz

3.1) Filesystem
Achtung
Achtung: Backup nicht vergessen!!!


Als erstes sollte man sich ein wenig mit dem Filesystem beschäfitigen, da ganz nach verwenddung ggf. ein anderes Filesystem verwendet werden sollte.


Zusammenfassung:
XFS: ausgezeichnete Leistung bei großen Dateien, dafür langsamere Geschwindigkeit bei kleinen Dateien (z.B. für ISO’s oder großen Downloads unter /home)


Reiserfs: ausgezeichnete Leistung bei kleinen Dateien (z.B. für viele kleine Dateien unter /var)


Ext3: durchschnittliche Leistung


Ext4: super Gesamtleistung (Leistungsprobleme bei sqlite und anderen Datenbanken)


JFS: gute Gesamtleistung (sehr geringe CPU-Last)


Btrfs: super Gesamtleistung (besser als ext4 ABER ggf. unstable)


3.2) Mount Optionen

/dev/partition /mnt/partition partitiontype option1,option2 0 0


Ein weitere Möglichkeit das Dateisystem zu optimieren, sind die “Mount Optionen”, diese trägst du in der Datei “/etc/fstab” ein. So kann man z.B. durch “relatime” oder “noatime” verhindern, dass die Zugriffszeiten in der Inodetabelle gespeichert werden und so die Festplattenaktivität reduziert werden.



sudo tune2fs -O dir_index /dev/partition


Mit dem vorigem Befehl wird die automatische Indizierung von Ordnerinhalten aktiviert, so dass man schneller aus die Daten zugreifen kann.
(wer ggf. von Ext3 auf Ext4 wechseln möchte kann dies tun: http://suckup.de/blog/2010/02/14/konvertiere-ext3-zu-ext4/)
Sowohl bei Ext3 als auch bei Ext4 wird ein Journal geschrieben, dieses kann man mit der Option “data=writeback” einschränken und somit die Preformance steigern, kann jedoch zu Problemen führen, da die metadata nun “träge” gespeichert werden.


Journal‘ – Langsamster und sicherster Modus. Nicht nur die Metadaten sondern auch die Nutzdaten werden zunächst in das Journal, und dann erst auf die Festplatte geschrieben.
Ordered‘ – Guter Kompromiss aus Sicherheit und Geschwindigkeit (Standard). Die Nutzdaten werden auf die Festplatte geschrieben sobald die Metadaten im Journal abgelegt wurden.
Writeback‘ – Schnell, dafür relativ unsicher. Die Nutzdaten werden sofort auf die Festplatte geschrieben ohne das gewartet wird bis die Metadaten im Journal abgelegt wurden.


tune2fs -o journal_data_writeback /dev/partition


mit dem vorherigem Befehl schreibt man das vorhandene Journal um…


/dev/partition / ext4 errors=remount-ro,noatime,nodiratime,data=writeback,barrier=0,nobh,commit=100,nouser_xattr 0 1


noatime” sagt aus, dass nicht gespeichert wird, wann die Datei angesehen wurde. (man liest eine Datei und gleichzeitig wird auf die Dateien geschrieben) Auch “barrier=0” trägt dazu bei, dass deine Daten unsicherer sind, die Option steigert jedoch die Performance. (so soll die Option einen sehr positiven Einfluss auf die Schreib-Performance von MySQL haben) Die Option “nobh” versucht “associating buffer heads” zu vermeiden und bringt eine kleine Performace verbesserung. Als nächstes kommt die Option “commit=100“, diese Option sagt aus, dass die Daten nur alle 100 Sekunden auf die Festplatte geschrieben werden, dafür verliet man ggf. auch 100 Sekunden bei einem Ausfall (default 5). “nouser_xattr” schaltet einige weitere Optionen vom Dateisystem aus und bringt noch einmal einen kleinen Performanceschub.



XFS -> zur optimierung kann man das Dateisystem mit dem folgedem Kommando anlegen …


mkfs.xfs -l internal,lazy-count=1,size=128m -d agcount=2 /dev/partition


… und die “Mount Option” -> “logbufs=8” in der fstab einfügen. Zudem kann man das gemountete XFS-Filesysteme per “filesystem reorganizer for XFS” Optimieren.


xfs_db -c frag -r /dev/partition


-> stellt den Fragmentationsgrad fest


xfs_fsr /dev/partition


-> defragmentiert die Partition (apt-get install xfsdump)


Die Option “data=writeback” beschleunigt das Dateisystem, kann jedoch zu Datenverlust beim Stromausfall führen. Auch “notail” beschleunigt Reiserfs bewirkt jedoch, dass zirka 5% mehr an Festplattenplatz benötigt wird. Zudem kann man mit dem nächsten Befehl bereits beim erstellen das Dateisystems dieses beschleunigen, indem man das Journal auf eine zweite Partition auslagert.


mkreiserfs –j /dev/hda1 /dev/hdb1



Dieses neue Dateisystem bietet “online Defragmentation”, “Optimierungen für SSDs”, “Snapshots” und viele weitere Sinnvolle Funktionen, wird jedoch momentan noch aktiv entwickelt.


Informationen zum optimieren von SSDs findest du hier -> https://wiki.archlinux.org/index.php/SSD#Tips_for_Maximizing_SSD_Performance


(Im Arch-Linux Wiki habe ich auch noch von der Möglichkeit gelesen “/usr” komplett zu komprimieren (aufs2 + squashfs-tools) da moderne CPUs schneller die Dateien entpacken können als das größere Daten von der Festplatte geladen werden können, leider habe ich diesbezüglich keine Infos zu Ubuntu gefunden.)


4.) CPU

Hier kann man in erster Lienie Overclocking betreiben und somit einiges an Geschwindigkeit herausholen, so habe ich z.B. aus einem “AMD Athlon II X3″ einen “AMD Athlon II X4″ gemacht. (PS: wer Fragen zur Hardware hat, sollte sich einmal das Computerbase-Forum anschauen, habe dort auch meinen neuen PC gemeinsam mit anderen Mitgliedern zusammengestellt -> “http://www.computerbase.de/forum/showthread.php?p=8532713” + Vorlagen für verschiedene Preisklassen http://www.computerbase.de/forum/showthread.php?p=3395405)


Wenn man auf der Software-Seite seine CPU besser nutzen möchte kann man einen optimierten Kernel bauen oder zumindest bei Arch-Linux sein System mit neuen “CFLAGS & CXXFLAGS” neu-kompilieren lassen. (https://wiki.archlinux.org/index.php/Pacbuilder) Falls jemand ein ähliches Programm für Ubuntu kennt, würde ich dies gerne erfahren. :-)


4.1) optimierten Kernel bauen

Download: KernelCheck – .deb


Download: Patch


Install: KernelCheck
dpkg -i *.deb


Starte KernelCheck
-> “custom complication”
-> “normal performance patch”
-> “Configure kernel options manually, auto-configure ALSA options for sound, Optimize the kernel, Install kernel package after complication”
-> “Apply custom path to kernel”


Nachdem die Dateien heruntergeladen und entpackt wurden, bekommst du eine Shell in der du den Patch einspielen musst.


cd linux
cp /home/USER/Desktop/patch-2.6.36-ck2 .
patch < patch-2.6.36-ck2 -p1


Nachdem du das Fenster wieder verlässt kannst du noch einige Optimierungen auswählen:


-> “Processor type and features”



4.2) optimierten Kernel (+ Brain Fuck Scheduler)


… man kann hier natürlich auch auf ppa zurückgreifen (jedoch noch nicht getestet)!


sudo add-apt-repository ppa:chogydan/ppa && sudo apt-get update
sudo apt-get install linux-ck-generic linux-ck-headers-generic


5.) RAM & swap


5.1) Auslagerung von Speicher
swappiness” ist eine Einstellung, welche dem Kernel mitteilt ob der RAM oder der SWAP bevorzugt werden soll. Der Wert der Variablen kann zwischen 0 und 100 liegen. Der Wert 0 bedeutet, dass der Kernel den Auslagerungsspeicher auf der Festplatte (swap) nur dann nutzt, wenn es nicht anders geht. Der Wert 100 bedeutet das genaue Gegenteil. Es wird so früh wie möglich ein unbenutzter Speicherbereich in den Swapspeicher geschoben.


vim /etc/sysctl.conf
vm.swappiness=20
vm.vfs_cache_pressure=50


5.2) Compcache
Compcache, auch als “ramzswap kernel module” bezeichnet erstellt Swap im Arbeitsspeicher und komprimiert diesen. So dass zwar die CPU wieder mehr zu tun hat, wir jedoch mehr Auslagern können, ausserdem hat dies den Vorteil, dass die Lese-/Schreizugriffe auf der Festplatte weiter reduziert werden.



5.3) tmpfs
Einen ählichen Ansatz, wie “Compcache” verfolgt auch “tmpfs” hier werden die Daten jedoch einfach in den Arbeitsspeicher geschrieben, ohne diese zu komprmieren. Wenn man jedoch genügent Speicher übrig hat, kann man so z.B. die “/tmp”-Daten in den Speicher auslagern.
vim /etc/fstab
tmpfs /tmp tmpfs defaults,noatime,nodev,nosuid,mode=1777 0 0
(nach diesem Prinzip kann man auch z.B. den Cache vom ff oder vom Chrome auslagern)


6.) Netzwerk & Internet


6.1) DNS
Ggf. sollte man schauen, ob man nicht einen schnelleren DNS-Server in seiner nähe findet ;-) -> http://suckup.de/blog/2010/02/13/find-a-fast-dns-server/
zumdem sollte man seinen eigenen Hostnamen in die der Datei “/etc/hosts” eintragen.
127.0.0.1 localhost
127.0.1.1 Rechnername
wird zu …
127.0.0.1 localhost Rechnername
127.0.1.1 Rechnername


Wer Spaß hat kann sich auch einen kleinen lokalen DNS-Cache installieren.
sudo apt-get install dnsmasq
vim /etc/dnsmasq.conf
listen-address=127.0.0.1
vim /etc/dhcp3/dhclient.conf
prepend domain-name-servers 127.0.0.1;
z.B.:
#supersede domain-name "suckup.de voku-online.de";
prepend domain-name-servers 127.0.0.1;
request subnet-mask, broadcast-address, time-offset, routers,
domain-name, domain-name-servers, host-name,
netbios-name-servers, netbios-scope;
vim /etc/resolv.conf
z.B.:
search suckup.de
nameserver 127.0.0.1
nameserver 8.8.4.4
vim /etc/resolv.dnsmasq.conf
resolv-file=/etc/resolv.dnsmasq.conf
listen-address=127.0.0.1
vim /etc/resolv.dnsmasq.conf
nameserver 8.8.4.4
vim /etc/resolv.conf
z.B.:
search suckup.de
nameserver 127.0.0.1
sudo /etc/init.d/dnsmasq restart


6.2) SYSCTL

In der Datei “sysctl.conf” kannst du Paramether für dein System einstellen.


wget -c http://www.rubyringtechnologies.com/files/sysctl.conf.txt -O ~/sysctl.conf
sed -i 's/\(net\.core\.hot_list_length\ =\ 256\)/\#\1/' ~/sysctl.conf
cat < ~/sysctl.conf >> /etc/sysctl.conf
sysctl -p


6.3) MTU


Typische MTU-Größen:
Medium MTU in Bytes
Hyperchannel 65535
Token Ring(4)(802.5) 4464
Token Ring(16) 17914
FDDI 4352
Ethernet 1500
Gigabit Ethernet
mit Jumboframes
9000
PPPoE (z. B. DSL) ≤ 1492
SLIP/PPP (low delay) 296
X.25 576
FibreChannel theoretisch unbegrenzt
ISDN 576
DQDB
HIPPI
ATM 4500, s. u.
ARCNET
802.11 2312 (WiFi)

Quelle: http://de.wikipedia.org/wiki/Maximum_Transmission_Unit


ping -Mdo -s 1500 8.8.8.8


-> mit dem vorherigem Befehl kannst du testen welche MTU funktioniert (z.B. 1500)


Konfig-Beispiel:

vim /etc/network/interfaces

iface eth0 inet static
address 192.168.0.1
network 192.168.0.0
gateway 192.168.0.254
netmask 255.255.255.0
mtu 1492


7.) preload, ureadahead etc.

ureadahead ist standardmäßig bereis bei Ubuntu installiert und lädt Programme bereits beim Bootvorgang in den RAM, falls man z.B. preload (apt-get install preload) einsetzten will, sollte man ureadahead deaktivieren, da es die selbe Aufgabe übernimmt. “preload” hat den Vorteil, dass es im Betrieb protokolliert welche Programme wirklich verwendet werden und nur diese bereits beim Boot in den RAM lädt, daher startet das System schneller, die Programm werden jedoch nicht schneller gestartet als mit ureadahead. (persönliche Meinung – nicht auf die Millisekunde gemessen) außerdem verursacht das Programm “preload” immer CPU-Last und verbraucht somit mehr Strom als wie ohne. ;-) Um den Boot-Vorgang näher zu analysieren soll man sich einmal “bootchart” (http://wiki.ubuntuusers.de/bootchart) anschauen.


8.) prelink

Wenn man den Start von Programmen beschleunigen will, kann man “prelink” (apt-get install prelink) ausprobieren, besonders bei KDE bringt dies einiges, da somit bei “dynamic linking” Programmen (Programm die nicht gelinkt sind, um z.B. Speicherplatz zu sparen) die Libraries nicht jedesmal bei geladen werden müssen. Prelink nutzt dies insofern aus, als dass es das Linken im Voraus ausführt und in der Programmdatei abspeichert. Somit kann man (fast) jedes Programm beschleunigen.


vim /etc/default/prelink

PRELINKING=unknown 

wird zu …

PRELINKING=yes 


http://wiki.ubuntuusers.de/Prelink


9.) localepurge

Nicht verwendete Sprachdateien zu entfernen erscheint zwar auf den ersten Blick nicht wirklich als Optimierung, jedoch hat sich in der Praxis gezeigt, dass einige Programm diese Sprachdateien z.B. beim Start in den Speicher laden, daher kann man so nicht nur Festplattenplatz, sondern ggf. auch Arbeitsspeicher einsparen und Programme schneller starten.



Quellen:

https://wiki.archlinux.org/index.php/Maximizing_Performance

http://sidux.com/index.php?module=Wikula&tag=SiduxTweaks

http://wiki.ubuntuusers.de/tuning

C-Programm – Größe von Variablen

Mit diesem kleinem Programm kannst du dir die minimale und maximale Größe von Variablen ausgeben lassen. :-)

#include <stdio.h>
#include <limits.h>
#include <float.h>

int main(void) {
        printf("min. char-Wert          : %d\n", SCHAR_MIN);
        printf("max. char-Wert          : +%d\n", SCHAR_MAX);
        printf("min. unsigned-char      : 0\n");
        printf("max. unsigned-char      : %u\n\n", UCHAR_MAX);

        printf("min. short-Wert         : %d\n", SHRT_MIN);
        printf("max. short-Wert         : +%d\n", SHRT_MAX);
        printf("min. unsigned-short     : 0\n");
        printf("max. unsigned-short     : %u\n\n", USHRT_MAX);

        printf("min. int-Wert           : %d\n", INT_MIN);
        printf("max. int-Wert           : +%d\n", INT_MAX);
        printf("min. unsigned-int       : 0\n");
        printf("max. unsigned-int       : %u\n\n", UINT_MAX);

        printf("min. long-Wert          : %ld\n", LONG_MIN);
        printf("max. long-Wert          : +%ld\n", LONG_MAX);
        printf("min. unsigned-long      : 0\n");
        printf("max. unsigned-long      : %lu\n\n", ULONG_MAX);

        printf("min. long long-Wert     : %lld\n", LLONG_MIN);
        printf("max. long long-Wert     : +%lld\n", LLONG_MAX);
        printf("min. unsigned-llong     : 0\n");
        printf("max. unsigned-llong     : %llu\n\n", ULLONG_MAX);


        printf("min. float-Wert         : %f\n", FLT_MIN);
        printf("max. float-Wert         : +%f\n", FLT_MAX);
        printf("float Genauigkeit       : %d\n\n", FLT_DIG);

        printf("min. double-Wert        : %lf\n", DBL_MIN);
        printf("max. double-Wert        : +%lf\n", DBL_MAX);
        printf("double Genauigkeit      : %d\n\n", DBL_DIG);

        printf("min. long double        : %Lf\n", LDBL_MIN);
        printf("max. long double        : +%Lf\n", LDBL_MAX);
        printf("long double Genu.       : %d\n\n", LDBL_DIG);

        return 0;
}


Ausgabe:

min. char-Wert : -128
max. char-Wert : +127
min. unsigned-char : 0
max. unsigned-char : 255

min. short-Wert : -32768
max. short-Wert : +32767
min. unsigned-short : 0
max. unsigned-short : 65535

min. int-Wert : -2147483648
max. int-Wert : +2147483647
min. unsigned-int : 0
max. unsigned-int : 4294967295

min. long-Wert : -2147483648
max. long-Wert : +2147483647
min. unsigned-long : 0
max. unsigned-long : 4294967295

min. long long-Wert : -9223372036854775808
max. long long-Wert : +9223372036854775807
min. unsigned-llong : 0
max. unsigned-llong : 18446744073709551615

min. float-Wert : 0.000000
max. float-Wert : +340282346638528859811704183484516925440.000000
float Genauigkeit : 6

min. double-Wert : 0.000000
max. double-Wert : +179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889[...]

min. long double : 0.000000
max. long double : +1189731495357231765021263853030970205169063322294624200440323733891737005522970722616410290336528882853545697807495577314427443153670[...]


Wenn du das nächste C-Programm einmal kompiliert hast und es mehrere male nacheinander ausführst siehst du, dass die Variable ggf. an einer anderen Stelle im Speicher abgelegt wurde.

#include <stdio.h>

int main(void) {
        int var=0;
        printf("Die Adresse von var lautet: %p\n", &var);
        return 0;
}