Autor | Zpráva | ||
---|---|---|---|
Oxidián Profil * |
#1 · Zasláno: 19. 6. 2014, 17:43:30
Tak teď si asi říkáte, proč chci napsat funkci ceil a floor. Protože jsem před chvílí zjistil, že volání jakékoliv funkce uvnitř smyčky (například při vypisování pixelů obrázku) náramně ubírá na výkonu. Tedy by bylo možné získat lepší výkon, když bych místo volání funkce ze smyčky použil vlastní algoritmus. Jenže nevím jak nato. Celý kód jsem již testoval ve předchozím vlákně o nalezení nejmenší a největší hodnoty. Už jsem dal pryč funkci round() a nastalo další zrychlení. Tak proč to neurychlit ještě více?
$R = round($varR * 255); $G = round($varG * 255); $B = round($varB * 255); $R = $varR * 255 < 0.0 ? ceil($varR * 255 - 0.5) : floor($varR * 255 + 0.5); $G = $varG * 255 < 0.0 ? ceil($varG * 255 - 0.5) : floor($varG * 255 + 0.5); $B = $varG * 255 < 0.0 ? ceil($varB * 255 - 0.5) : floor($varB * 255 + 0.5); |
||
juriad Profil |
#2 · Zasláno: 19. 6. 2014, 18:09:13
Docela dobře funguje:
function r($x) { return (int) ($x + 0.5) - ($x < 0); } volání funkce round: 4.0317828655243 volání funkce r: 5.566967010498 inline výpočet: 3.4816009998322 |
||
abc Profil |
#3 · Zasláno: 19. 6. 2014, 21:10:55
nevím, nakolik to bude rychlejší (možná to bude spíš pomalejší), ale pokud jsou výsledkem čísla od 0-255, tak by k tomu asi šlo přistupovat jako ke stringu a když narazíš na
. , tak máš zaokrouhleno dolu a podle dalších čísel za desetinnou tečkou případně přičítat 1
|
||
Oxidián Profil * |
#4 · Zasláno: 19. 6. 2014, 22:17:27
juriad:
Co se týče rychlosti není v tom rozdíl, tvoje varianta je možná nepatrně pomalejší než když použiju volání ceil a floor. Možná to spomaluje ten casting. po odstranění funkce round: A) 1.394 1.455 1.416 B) 2.533 2.652 2.64 2.675 Juriadova variace: A) 1.443 1.44 1.39 B) 2.681 2.688 2.78 2.717 |
||
Joker Profil |
#5 · Zasláno: 19. 6. 2014, 22:35:21
Oxidián:
Jestli je nutné to optimalizovat až do takové míry, zkusil bych to místo PHP napsat rovnou v Céčku. |
||
juriad Profil |
#6 · Zasláno: 19. 6. 2014, 22:44:02
Mně na mojí mašině vychází jiné statistiky:
volání round: 44.26890707016 volání ceil_floor: 106.42230200768 volání r: 58.501924037933 inline r: 36.389965057373 inline r bez korekce: 22.217283964157 floor: 58.362727880478 inline r bez přetypování: 25.081015110016 pouze přičtení 0.5: 17.573384046555 inline floor & ceil: 64.921782016754 Jedná se o: Linux judy 3.14.6-1-ARCH #1 SMP PREEMPT Sun Jun 8 10:08:38 CEST 2014 x86_64 GNU/Linux PHP 5.5.13 (cli) (built: May 29 2014 05:46:58) |
||
Oxidián Profil * |
#7 · Zasláno: 20. 6. 2014, 08:54:16 · Upravil/a: Oxidián
Já testoval jen 67500 cyklů v rámci svého obrázku a v rámci celého programu na vygenerování obrázku, kolik to trvá dohromady.
A počítám na tři místa což je rychlejší. Ale nevím jaký to má vliv na přesnost barev při převodu na hsv. Protože já okem žádný rozdíl nevidím, ale nezkoušel jsem dělat žádné úpravy na fotce. Jestli tam někde náhodou je odstín 61 místo 60 apod. tak to poznat nebude. |
||
juriad Profil |
Můj poslední benchmark probíhal takto:
$r=50000000; echo "volání XXX: "; $t =microtime(true); for ($i = -$r; $i<$r; $i+=0.3) { # sem jsem dal testovaný kód } echo microtime(true) - $t; echo "\n"; Pokud skutečně v tvém případě je volání floor nebo ceil podle ternárního operátoru rychlejší, tak v mém případě není. Jedná se o řádky „inline r“ a „inline flloor & ceil“. Je to dokonce v mém případě horší než volání funkce round, které je u mě dost rychlé. Oxidián: Jak jsi zjistil, že počítáš na 3 místa? O tom vůbec nevím, že by to šlo nastavit. PHP, pokud vím, má jediný typ pro čísla s plovoucí desetinnou čárkou - tento typ je interně realizován jako double , který je známý z jiných jazyků.
Jakákoli jiná reprezentace desetinných čísel musí být nutně pomalejší. Neprovádíš náhodou nějaké chujoviny se stringama? |
||
Oxidián Profil * |
#9 · Zasláno: 20. 6. 2014, 16:33:38
juriad:
V php.ini ; The number of significant digits displayed in floating point numbers. precision = 12 nebo ini_set("precision", 4); Se stringama vůbec nepracuju. |
||
pepiik Profil * |
#10 · Zasláno: 22. 6. 2014, 02:26:11
juriad: tvoje funkce počíta špatně
$x = -0.4; round($x); // -0 r($x); // -1 |
||
Joker Profil |
#11 · Zasláno: 22. 6. 2014, 09:37:40
pepiik:
Protože round, floor a ceil jsou tři různé způsoby zaokrouhlení. |
||
juriad Profil |
#12 · Zasláno: 22. 6. 2014, 09:56:34
pepiik:
Máš pravdu, špatně jsem to testoval. Chyba byla u argumentů s hodnotou mezi -0.5 a 0. Oprava: function r($x) { return (int) ($x + 0.5) - ($x <= -0.5); } |
||
1Pupik1989 Profil |
#13 · Zasláno: 24. 6. 2014, 12:10:50
Já používání následující:
round($n) === ($n + 0.5) >> 0; ceil($n) === ($n + 1) >> 0; floor($n) === $n >> 0; |
||
Časová prodleva: 10 let
|
0