Portál AbcLinuxu, 12. července 2025 07:33
Po vzoru Leoše Literáka se přiznám ke své v mém případě spíš neznalosti.
Píšu do školy javový program na kreslení animací kinematických křivek. Celé to je postavené na výpočtu jednotlivých bodů a jejich spojování přímkami. Výpočty jsou celkem triviální, kreslení většiny křivek také. Najdou se však křivky, které mají i 15000 bodů. Vykreslení takové křivky trvá docela dlouho (cca 18 ms). Proto jsem se rozhodl optimalizovat.
Optimalizace se zadařila a čas jsem stáhl na třetinu. Přestala však fungovat jiná věc. Při měnění parametrů za běhu se program začal nepříjemně trhat. Dlouhou dobu jsem nemohl zjistit, kde je problém. Celou optimalizaci jsem párkrát předělal, pohrál jsem si se synchronizací a stále nic.
Po nějakém čase mě napadlo porovnat kód se starším, který fungoval v pořádku. Jediný podstatný rozdíl byl ve volání garbage collectoru při každé změně. Přišlo mi to divné, ale zkusit jsem to musel. K mému překvapení se po zakomentování onoho řádky všechno vrátilo do správných kolejí.
Po podrobnějším měření jsem s hrůzou zjistl, že volání System.gc()
zažere cca 70 ms. Jindy by to nevadilo, ale když potřebuju překreslovat jednou za 10 ms, tak je to znát.
Je až k nevíře, jak mě objevení téhle prkotiny potěšilo :) ... Chybami se člověk učí :)
Tiskni
Sdílej:
Kdybych měl pokaždý psát blogspot, když se chytim za nos , ale dobrý ...
Já vim. Jsou věci v životě, co člověka naučí nadhledu a věci, co rozšíří obzory.
System.gc()
by se pokud možno nemělo volat nikdy.
OutOfMemoryError
. V první fázi jsem to řešil tou nejhorší možnou cestou - volat explicitně System.gc()
. Program se zpomalil naprosto brutálně, takže bylo hned jasné, že tudy cesta nevede BTW ani jsem netušil (a zjistil jsem to až teď), že existuje věda stringologieKdysi jsem kdesi sehnal 220stránkové PDFko celé věnované algoritmům hledání podřetězce v řetězci. Velmi poučné
Ale 70 ms na mém docela silném stroji mi vyrazilo dech.To buďte rád, že ne 10 minut (sic!).
A kdyz zacinate s Javou, tak kazdy si asi projde spojovani retezcu pomoci String += anebo StringBuffer().Spojování pomocí
String
+= každý relativně snadno zavrhne, až zjistí, že je to O(n^2). Tedy spíše mu bude divné, že je to najednou nějak strašně pomalé. Ale StringBuffer
je z jiného soudku, už proto, že StringBuilder
je až záležitost verze 1.5, takže leckdo může StringBuffer
používat čistě ze zvyku.
+=
neefektivní, je známá věc. Ale jak je to s těma ostatníma, hlavně se StringBuilderem
, budu muset nastudovat, nebo otestovat (a nebo mi to někdo osvětlíte?) Vnukli jste mi dobrou myšlenku na studium. Díky+=
, maximálně StringBuffer.append()
stačilo :)
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.