Pokazywanie postów oznaczonych etykietą c. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą c. Pokaż wszystkie posty

piątek, 24 czerwca 2022

C vs Python

Postanowiłem porównać szybkość znajdowania liczb pierwszych w językach programowania C i Python najprostszym algorytmem sprawdzającym dzielniki badanej liczby.

Dla przypomnienia: Liczba pierwsza to liczba naturalna, która ma dokładnie dwa dzielniki naturalne - jedynkę i samą siebie. Wykaz początkowych liczb pierwszych: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271 itd. Liczby naturalne większe od 1, które nie są pierwsze, nazywa się liczbami złożonymi. Liczby 4 i 6 są więc przykładami liczb złożonych. Z podanych definicji wynika, że liczby 0 i 1 nie są ani pierwsze, ani złożone. Liczby pierwsze są stosowane w niektórych algorytmach kryptograficznych np. RSA.

Algorytm jest bardzo prosty: dla badanej liczby naturalnej n sprawdzamy, czy liczby naturalne należące do przedziału [2, ... ,  √n] są dzielnikami naszej liczby n. Jeżeli okazało by się, że któraś z tych liczb jest dzielnikiem naszej liczby n, oznacza to, że nasza liczba nie jest pierwsza.

Mój test polega na tym, że mierzony jest czas sprawdzenia 8 milionów liczb, czy są liczbami pierwszymi. Pierwszy program jest napisany w języku C:

#include <stdio.h>
#include <math.h>
#include <time.h>

#define FALSE 0
#define TRUE  1
  
int is_prime(int n) {
  if (n<2) {
    return FALSE;
  }
  else if (n==2) {
    return TRUE;
  }
  else {
    for (int i=2; i<=(int)ceil(sqrt(n)); i++) {
      if (n % i == 0) {
        return FALSE;
      }
    }
    return TRUE;
  }
}

int main() {
  int max = 8000000;
  time_t t1, t2;
  
  printf("Checking %d numbers. Please wait...\n", max);
  
  t1 = time(NULL);
  
  for(int i=1; i<=max; i++) {
    is_prime(i);
    //printf("%d   %d\n", i, is_prime(i));
  }
  
  t2 = time(NULL);
  printf("Done in %ld seconds.\n", t2-t1);
}

Program kompilujemy następująco:

gcc primes-search.c -o primes-search -lm

lub

cc primes-search.c -o primes-search -lm

Drugi program jest w języku Python 3:

import math
import time

def is_prime(n):
  if n < 2:
    return False
  elif n == 2:
    return True
  else:
    # range = 2..math.ceil(math.sqrt(n))
    for i in range(2, (int)(math.ceil(math.sqrt(n))) + 1):
      if n % i == 0:
        return False
    return True
    

max = 8000000

print("Checking %d numbers. Please wait..." % max)

t1 = time.time()

for i in range(1, max):
  is_prime(i)
  #print("%d   %d" % (i, is_prime(i)))
  
t2 = time.time()
print("Done in %d seconds." % (t2-t1))

Kody źródłowe są tutaj:

https://github.com/adamblaszczyk/primes-search__c_vs_python

Czasy wykonania programów:

LENOVO ThinkPad E440, Intel Core i3-4000M 2.4GHz - FreeBSD 13.0 64-bit

.c - 21 sekund

.py - 124 sekundy


piątek, 16 sierpnia 2019

Pożyteczne (techniczne) linki

Poniżej umieszczam trochę pożytecznych linków, z których czasami korzystam.

DistroWatch.com - dokładny przegląd dystrybucji Linuksa i BSD:
https://distrowatch.com/

Cheat.sh - ściągawka do komend Unix/Linux i języków programowania:

Explain Linux Commands - wpisujemy pełną komendę np. ps -aux i dostajemy pełne wyjaśnienie, co robi komenda oraz jej parametry:

What is my IP - mój publiczny i prywatny adres IP:
https://www.cleancss.com/what-is-my-ip/

Default Router Settings - domyślne nazwy i hasła użytkowników oraz adresy IP routerów, modemów, kamer IP i innych urządzeń sieciowych:
https://www.cleancss.com/router-default/

BezKompilatora.pl - ciekawy blog o Linuksie:
https://www.bezkompilatora.pl/

Crontab Guru - edytor (kreator) tabeli crontab dla harmonogramu zadań cron:
https://crontab.guru/

repl.it - kompilatory online dla różnych języków programowania:
https://repl.it/

Circuit Simulator - symulator układów elektronicznych w przeglądarce:
http://lushprojects.com/circuitjs/

Crypto-IT : Protokoły TCP/IP - opis TCP/IP:
http://www.crypto-it.net/pl/teoria/protokoly-tcp-ip.html

Codecademy - kursy online z języków programowania:
https://www.codecademy.com/

Rosetta Code - różne zadania programistyczne w bardzo wielu językach programowania:
http://www.rosettacode.org/wiki/Category:Programming_Tasks
np. najprostszy program Hello World napisany w ponad 400 różnych językach programowania:
http://www.rosettacode.org/wiki/Hello_world/Text

SS64 - opis komend wiersza poleceń dla systemów Linux, macOS i Windows oraz opis poleceń i funkcji dla SQL, VBS i PowerShell:
https://ss64.com/

VirusTotal - można sobie online przeskanować plik za pomocą różnych silników antywirusowych:
https://www.virustotal.com

WolframAlpha - strona ta formułuje odpowiedź na pytanie zadane w języku naturalnym, wykonuje obliczenia, przedstawia dane statystyczne, rozwiązuje równania itp.:
https://www.wolframalpha.com/

ark.intel.com - specyfikacje produktów Intela:
https://ark.intel.com

FORBOT - elektronika, Arduino, Raspberry Pi, kursy:
https://forbot.pl/blog/

BlogIT by Artur Dębski - pożyteczne notatki z różnych dziedzin IT:
http://blogit.one.pl/news_cats.php

Kalkulator IP - na podstawie adresu IP i maski oblicza adres sieci, adres rozgłoszeniowy oraz ilość hostów w sieci:
https://42.pl/ipcalc/

--- Na koniec moje dwa ulubione na dzień dzisiejszy systemy operacyjne ---

FreeBSD:
https://www.freebsd.org/
https://www.freshports.org/
https://pl.wikipedia.org/wiki/FreeBSD

Linux Mint:
https://www.linuxmint.com/
https://pl.wikipedia.org/wiki/Linux_Mint

niedziela, 17 kwietnia 2016

Jednolinijkowe generatory melodii

Na blogu countercomplex znalazłem ciekawy artykuł jak generować 8-bitowe oldskulowe (podobne do tych z gier z lat 80-tych) melodie za pomocą jednej linijki kodu w języku C. Poniżej dwa przykładowe programy:

main(t){for(t=0;;t++)putchar((t*5&t>>7)|(t*3&t>>10));}

main(t){for(t=0;;t++)putchar((t>>6|t|t>>(t>>16))*10+((t>>11)&7));}

Powyższe programy kompilujemy następująco:

gcc sound.c -o sound

Aby odtworzyć dźwięk z naszego generatora o nazwie sound, należy przekierować jego standardowe wyjście na standardowe wejście odtwarzacza audio np. aplay (Linux) za pomocą potoku |:

./sound | aplay

W komentarzach do artykułu na blogu countercomplex jest dużo innych przykładów - można poeksperymentować modyfikując funkcję putchar().

Źródła
http://countercomplex.blogspot.com/2011/10/algorithmic-symphonies-from-one-line-of.html 
http://countercomplex.blogspot.com/2011/10/some-deep-analysis-of-one-line-music.html 
 

środa, 9 marca 2016

Kody ASCII

Ostatnio potrzebowałem skorzystać z kodów ASCII w konsoli systemu Windows. Oczywiście można znaleźć gotowe tablice z kodami ASCII w internecie, ale rozszerzone kody ASCII są zależne od systemu operacyjnego oraz strony kodowej. Tak więc stworzyłem prosty programik ascii-codes, który wyświetla symbole (znaki) dla kodów ASCII od 0 do 255.


ASCII (ang. American Standard Code for Information Interchange) – 7-bitowy kod przyporządkowujący liczby z zakresu 0−127: literom alfabetu angielskiego, cyfrom, znakom przestankowym i innym symbolom oraz poleceniom sterującym. Na przykład litera „a” jest kodowana jako liczba 97, a znak spacji jest kodowany jako 32. Znaki ASCII dzielimy na:
- sterujące (kody 0 - 31 oraz 127),
- drukowalne (kody 32 - 126).
Ponieważ kod ASCII jest 7-bitowy, a większość komputerów operuje na 8-bitowych bajtach, dodatkowy bit można wykorzystać na powiększenie zbioru kodowanych znaków do 256 symboli, a więc mamy:
- znaki ASCII rozszerzone (kody 128 - 255) - uzależnione od strony kodowej.

Stronę kodową konsoli Windows sprawdzamy poleceniem:

mode con cp

a ustawiamy poleceniem:

mode con cp=[strona kodowa]

np.

mode con cp=1250

Kod programu ascii-codes.c:
/*
 *  -----------------------------------------
 *  ASCII Codes 1.0
 *  -----------------------------------------
 *  Author: Adam Blaszczyk
 *          http://wyciekpamieci.blogspot.com
 *  Date:   2016-03-08
 *  -----------------------------------------
 *  
 *  Compilation (Linux, Windows):
 *         gcc ascii-codes.c -o ascii-codes -Wall
 *
 *  Usage:
 *         ascii-codes
 *         - ASCII and Extended ASCII *printable* characters between 32 and 255
 *         ascii-codes min
 *         - ASCII and Extended ASCII characters between [min] and 255
 *         ascii-codes min max
 *         - ASCII and Extended ASCII characters between [min] and [max]
 *
 */

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
  
  int ch;
  int min = 32;
  int max = 255;

  if(argc == 2)
    min = atoi(argv[1]);
  if(argc == 3) {
    min = atoi(argv[1]);
    max = atoi(argv[2]);
  }

  printf("\n");
  printf("  ASCII CODES\n");
  printf("  ==============================================\n");
  printf("     0 -  31; 127 --> ASCII control characters\n");
  printf("    32 - 126      --> ASCII printable characters\n");
  printf("   128 - 255      --> Extended ASCII characters\n");

  printf("\n");
  printf("  +-------+------+-----------+\n");
  printf("  |  DEC  |  HEX | Character |\n");
  printf("  +-------+------+-----------+\n");
  
  for(ch = min; ch <= max; ch++) {
    printf("  |  %03d  |  %02X  |     %c     |\n", ch, ch, ch);
  }
  
  printf("\nPress [ENTER] to exit...");
  getchar();

  return 0;
}
https://github.com/adamblaszczyk/ascii-codes 

Program da się skompilować pod Windows i Linux za pomocą gcc:

gcc ascii-codes.c -o ascii-codes -Wall

Przykładowe użycie programu:

ascii-codes
Wyświetla drukowalne znaki ASCII o kodach od 32 do 255,

ascii-codes 1
Wyświetla znaki ASCII o kodach od 1 do 255,

ascii-codes 174 181
Wyświetla znaki ASCII o kodach od 174 do 181.
 

piątek, 30 października 2015

valgrind - szukanie wycieków pamięci

Chciałbym zaprezentować pożyteczny program konsolowy valgrind, który bada wycieki pamięci w programach.

Wyciek pamięci (ang. memory leak) – niezamierzone użycie pamięci przez program komputerowy, gdy nie zwalnia on zaalokowanej wcześniej pamięci, która nie jest już mu potrzebna.

Wycieki pamięci są efektem bardzo niepożądanym. Program bowiem zajmuje coraz więcej pamięci, ale nie jest w stanie jej wykorzystać ani zwolnić. Szczególnie w aplikacjach, które działają przez długi czas (w większości serwerowych), efekt wycieku pamięci stopniowo narasta. Sam wyciek prowadzi do spadku wydajności systemu, w skrajnym przypadku zawieszenia się programu lub innych programów, którym system nie może przydzielić wystarczającej ilości pamięci, a nawet zablokowania całego systemu operacyjnego. Kod programu, który powoduje wycieki pamięci, jest kodem błędnym.

Użycie programu valgrind jest bardzo proste:

valgrind nazwa_programu

np.:

valgrind putty
valgrind ./myprog

Wynikiem powyższych poleceń jest uruchomienie danego programu, a po jego zakończeniu wyświetlenie ilości bajtów, które wyciekły.

Program valgrind przydaje się, gdy na komputerze uruchamiamy program, który po pewnym czasie zaczyna "mulić". Można wtedy sprawdzić, czy nie ma dużych wycieków pamięci.

W językach programowania takich jak Java czy C# problem wycieków pamięci został częściowo zniwelowany poprzez zastosowanie odśmiecania pamięci (ang. Garbage Collector). W językach C i C++ programista musi zwalniać pamięć. Poniżej przykład programu w C, który nie zwalnia zaalokowanej wcześniej pamięci na zmienną typu int (4 bajty):

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
  int *x = malloc(sizeof(int));
  *x = 16;
  printf("%d\n",*x);
  return 0;
}

Powyższy kod kompilujemy następująco:

gcc memleak.c -o memleak

Sprawdzamy wycieki pamięci:

valgrind ./memleak

Dostajemy informację, że wyciekły 4 bajty.

Poprawnie napisany program powinien zawierać funkcję free(), która zwalnia zarezerwowaną wcześniej pamięć:
 
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
  int *x = malloc(sizeof(int));
  *x = 16;
  printf("%d\n",*x);
  free(x);
  return 0;
}