Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: Pascal: Sinifunktioiden likiarvo kantsii laskea ite! ;) Ainaski Pascalissa

PetriKeckman [30.05.2023 07:47:35]

#

Se meinaan on jonkin verran tehokkaampaa ;) Taylorin sarjalla tietty. https://fi.wikipedia.org/wiki/Taylorin_sarja Ainakin tässä testissä.

Panen tähän vielä toistamiseen emojin: ;) etteivät tosikko nörtit ota liian vakavasti.

EDIT: koodi ei tuota samoja arvoja, mutta jos skulataan muutamien desimaalien tarkkuuksilla... :)

.
.
.
996           -1.14874648645606129260E-0001
997           -8.97967480497951136404E-0001
998           -8.55473151969687433771E-0001
999           -2.64607527370641256045E-0002
1000            8.26879540532002560991E-0001
  1       8.4147098480789650E-001            8.41470984807896506665E-0001
  2       9.0929742682564108E-001            9.09297426825681695377E-0001
  3       1.4112000785871492E-001            1.41120008059867222102E-0001
  4      -7.5680257873961398E-001           -7.56802495307928251402E-0001
  5      -9.5893316519659622E-001           -9.58924274663138468875E-0001
  6      -2.7981606363561601E-001           -2.79415498198925872810E-0001
  7       6.5698659871878906E-001            6.56986598718789090406E-0001
  8       9.8935824662338001E-001            9.89358246623381777825E-0001
  9       4.1211848521660249E-001            4.12118485241756569732E-0001
 10      -5.4402112881599074E-001           -5.44021110889369813432E-0001
Taylorin sarjalla aikaa meni 1.5999586321413517E-002
Sini funktiolla aikaa meni 2.3000151850283146E-002
program Taylorinsarja;
uses sysutils;
VAR t1,t2,t3,t4: Real;
	testi:LongInt;
FUNCTION potenssi(x: Real;i: LongInt): Real;
VAR tul: Real;
	p:Byte;
BEGIN
	tul:=1;
	FOR p:=1 TO i DO
		tul:=tul*x;
	potenssi:=tul;
END;
FUNCTION kertoma(luku:LongInt):Real;
VAR kerroin,
	tulos:Real;
BEGIN
	kerroin:=1;
	tulos:=1;
	WHILE kerroin<>luku DO
	BEGIN
		kerroin:=kerroin+1;
		tulos:=tulos*kerroin;
	END;
	kertoma:=tulos;
END;
FUNCTION Taylorinsarja(x: Real): Real;
VAR tulos, jasen1, jasen2: Real;
	indeksi, apuri: LongInt;
BEGIN
	indeksi:=1;
	tulos:=0;
	apuri:=Trunc(x/(2*Pi));
	x:=x-apuri*2*Pi;
	REPEAT
		jasen1:=Real(potenssi(x, indeksi))/Real(kertoma(indeksi));
		jasen2:=Real(potenssi(x, indeksi+2))/Real(kertoma(indeksi+2));
		tulos:=tulos+jasen1-jasen2;
		indeksi:=indeksi+4;
	UNTIL indeksi>20;
	Taylorinsarja:=tulos;
END;
BEGIN
	t1:=now;
	FOR testi:=1 TO 1000 DO
	BEGIN
		WRITELN(testi:3,Taylorinsarja(Real(testi)):30);
	END;
	t2:=now;
	t3:=now;
	FOR testi:=1 TO 1000 DO
	BEGIN
		WRITELN(testi:3,Sin(Real(testi)):40);
	END;
	t4:=now;
	FOR testi:=1 TO 10 DO //tulostetaan vielä testit...
	BEGIN
		WRITELN(testi:3,Taylorinsarja(Real(testi)):30, Sin(Real(testi)):40);
	END;


	WRITELN('Taylorin sarjalla aikaa meni', (t2-t1)*86400);
	WRITELN('Sini funktiolla aikaa meni', (t4-t3)*86400);
END.

Metabolix [30.05.2023 18:32:20]

#

Pysyykö testin tulos samana, jos lasket ensin sinillä ja sitten vasta sarjalla? Tämän jälkeen kannattaa myös poistaa tulostus mitattavasta koodista ja kokeilla uudestaan. Ylipäänsä sadasosasekunneissa liikkuviin tuloksiin ei kannata suhtautua vakavasti, vaan kannattaa lisätä reilusti kierroksia nopeustestiin.

PetriKeckman [30.05.2023 19:18:11]

#

En kässää miksi suoritusjärjestys vaikuttaisi asiaan, mutta vaihdoin nyt sitä ja laskin loopeissa 10 miljoonaa arvoa.

Sama järjestys ja 10 miljoonaa sarjan arvoa ilman tulostusta:

Taylorin sarjalla aikaa meni 7.6769995735958219E+000
Sini funktiolla aikaa meni 3.9000052493065596E-001

Vaihdettu järjestys ja 10 miljoonaa arvoa ja siis ilman tulostusta:

Taylorin sarjalla aikaa meni 7.8359996667131782E+000
Sini funktiolla aikaa meni 3.5100015811622143E-001

Eli sini funktio HUOMATTAVASTI nopeampi :)

Täytyy rehellisesti myöntää, että jouduin eilen vähän etsimään tapausta, missä Taylorilla saatiin nopeampi tulos :) No, sanoinhan, että tämä oli sellainen hupi testi...Leikittelin ajatuksella, että Taylorilla saataisiin nopeampi tulos - petyin ja etsin väkisin jonkinlaista tapausta, missä saadaan.

Metabolix [31.05.2023 18:06:39]

#

PetriKeckman kirjoitti:

En kässää miksi suoritusjärjestys vaikuttaisi asiaan,

Alkuperäisessä koodissa on mukana tulostus, ja tämä tulostus vie tosiasiassa enemmän aikaa kuin laskeminen. Tulostus usein myös hidastuu, kun tekstiä on ruudulla ja konsoli-ikkunan puskurissa entistä enemmän. Lisäksi pitemmässä testissä voisi käydä niin, että prosessori on aluksi hetken turbotilassa mutta lämmön noustessa palaa normaaliin nopeuteen (erityisesti läppärin tapauksessa). Ajattelin, että ehkä huomaisit itse kaiken tämän, kun testaisit koodia vähän eri tavoin.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta