Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: anonym 08. 06. 2018, 23:20:32
-
Mám tady problematický 350mg zip archiv, se spoustou souborů. Nativnímu windows unzipu to trvá několik minut, než to odzipuje. 7zip to má za 4 vteřiny. A teď Java, ta si dnes u mě šplhla:
Nejprve to vypadalo bledě. Použil jsem ze standardního JDK ZipFile a k tomu standardní 50x olajkovaný source code ze stackoverflow. Uvařil jsem si kávu, pohladil jsem psa a sednul k tomu. Výsledek? Naprostá katastrofa, trvalo to několik minut a počítač hořel!!! Zkoušel jsem to zparalelizovat, CPU jsem vytížil na 100% a stejně to trvalo několik minut. Už už jsem nadával, že si standardní knihovna z JDK nedokáže pořádně svižn odzipovat soubory, vzhledem k tomu že JARko je zip. Ale nevzdal jsem se. Odskočil jsem si na záchod, vrátil se k PC a začal jsem Googlit.
Tak jsem googlil a našel jsem knihovnu Zip4J. Neskutečná záležitost! Vážení, 6 vteřin a je to kompletně odzipované!!! A navíc to konečně dělal člověk a tak se to dobře používá:
try {
ZipFile zipFile = new ZipFile(input);
zipFile.extractAll(output.getPath());
} catch (ZipException e) {
e.printStackTrace();
}
A tohle je ten pomalý hrozivý ZipFile z JDK, tragedie:
try (ZipFile archive = new ZipFile(archiveFile.toFile())) {
// sort entries by name to always created folders first
List<? extends ZipEntry> entries = archive.stream()
.sorted((a, b) -> a.getName()
.compareTo(b.getName()))
.collect(Collectors.toList());
// copy each entry in the dest path
for (ZipEntry entry : entries) {
Path entryDest = destPath.resolve(entry.getName());
if (entry.isDirectory()) {
Files.createDirectory(entryDest);
continue;
}
Files.copy(archive.getInputStream(entry), entryDest);
}
}
V JDK by se měli pochlapit a ten hrozný ZipFile smazat.
HOŠI, víte co to znemená? Že jsme to zase těm C-šerpistům nandali 8)
Ale ten hlavní důvod proč to píšu je, jakto že je to sakra skoro tak rychlé jako v céčku psaný 7zip???
-
Za to může JIT s mikrooptimalizacemi. Dobře napsaný program v Javě je prakticky stejně rychý, jako by byl v C.
-
Za to může JIT s mikrooptimalizacemi. Dobře napsaný program v Javě je prakticky stejně rychý, jako by byl v C.
Ani náhodou: https://benchmarksgame-team.pages.debian.net/benchmarksgame/faster/gcc-java.html
-
Tak je super, že to je o tolik rychlejší.
Akorát to pořád používá java.util.zip.Inflater z JDK, viz https://github.com/supasate/zip4j/blob/master/src/net/lingala/zip4j/io/InflaterInputStream.java.
Třída Inflater používá nativní metodu int inflateBytes(long addr, byte[] b, int off, int len).
Můžeme jen hádat, jaká by byla rychlost Inflateru v čisté Javě by nativních metod.
-
jakto že je to sakra skoro tak rychlé jako v céčku psaný 7zip?
Proč by to tak rychlé být nemělo?
-
[quote author=anonym link=topic=18719.msg268818#msg268818 date=1528492832]
A tohle je ten pomalý hrozivý ZipFile z JDK, tragedie:
Tragédie to je. Proč se ty soubory vybalují napřeskáčku, v abecedním pořadí??
Tohle patří na http://thedailywtf.com - a nezapomeň se napráskat, že jsi tuhle sračku nejen našel, ale i použil jako benchmark!
-
[quote author=anonym link=topic=18719.msg268818#msg268818 date=1528492832]
A tohle je ten pomalý hrozivý ZipFile z JDK, tragedie:
Tragédie to je. Proč se ty soubory vybalují napřeskáčku, v abecedním pořadí??
Tohle patří na http://thedailywtf.com - a nezapomeň se napráskat, že jsi tuhle sračku nejen našel, ale i použil jako benchmark!
To je úplně jedno jak se rozbalijují ty chytráku, trvá to stejně kravsky dlouho setřízené i nesetřízené.
-
trvá to stejně kravsky dlouho setřízené i nesetřízené.
Tak určitě... ::) ::) ::)
NEsouhlasím se zpracováním nepotřebných osobních údajů, zejména v rozsahu debilního checkboxu na fóru.
-
Předpokládám, že oba používají Deflater ze standardní Java, který je založený na zlib napsaný v C.
Takže pomalost bude v něčem jiném. Za prvé původní algoritmus vyžaduje random access, v závislost na velikosti souborů a různých cache může být pomalejší. Hlavně bych ale zavíral input stream, možná se Java snaží otvírat víc file handlers než je nutné nebo je tam přebytečná synchronizace:
try (InputStream entryInput = archive.getInputStream(entry)) {
Files.copy(entryInput, entryDest);
}
Jako další možnost do benchmark bych zahrnul ještě novější commons-compress, a multi-thread k tomu. Kdysi jsem tam posílal commit, který eliminoval lockování při paralelním čtení z více threadů (za předpokladu, že jde o standardní FileChannel).
-
Zkoušel jsi to přes GrálVM (https://www.root.cz/clanky/pribehy-z-vyvoje-nejrychlejsiho-virtualniho-stroje-na-svete/?utm_medium=plejs) pustit v GrááálVM stroji (https://www.root.cz/clanky/pribehy-z-vyvoje-nejrychlejsiho-virtualniho-stroje-na-svete/?utm_medium=bejs)? stačí vzít zdrojáky 7zipu (klidně ve fortranu) a polyglotně to spojit s javou ,terá má v GraalVM (https://www.root.cz/clanky/pribehy-z-vyvoje-nejrychlejsiho-virtualniho-stroje-na-svete/?utm_kampaň=babiš) výsadní postavení. Třeba tam s grálem (https://www.root.cz/clanky/pribehy-z-vyvoje-nejrychlejsiho-virtualniho-stroje-na-svete/?utm_medium=plebejs&utm_link=hot-baby) najdeš hotspot a budeš král
-
je ten .zip uverejnitelny?
-
Jestli tady (alespoň částečně) neplatí, že je sice rychlý, ale nebezpečný, viz třeba:
https://github.com/snyk/zip-slip-vulnerability
zip4j vulnerable... ;)
-
je ten .zip uverejnitelny?
https://www.liferay.com/downloads Bundled with Tomcat
-
je ten .zip uverejnitelny?
https://www.liferay.com/downloads Bundled with Tomcat
Ne že bych dělal s Liferayem, on je to jenom takova mrdka, že na něm dělám benchmarky. Na kompu se mi spuští 120 vteřin :D