[Provocare] I.P.-uri unice intr-un fisier 120GB
Last Updated: Apr 08 2021 12:09, Started by
dani.user
, Apr 06 2021 20:13
·
0

#19
Posted 07 April 2021 - 09:40

cu ce te ajuta sa faci un hash în loc sa le parsezi? sau sa le pui în sorted set fata de soluția de mai sus? |
#20
Posted 07 April 2021 - 09:53

pai care ar fi diferenta daca parsezi ip-ul in loc de un hah sau utilizezi de exemplu un set normal fata de un sorted set? nu inteleg la ce te ajuta daca trebuia sa fie gata ieri
![]() |
#21
Posted 07 April 2021 - 09:59

pentru cerința data eu nu m-as complica sa le parsez ci as face un hash(long) pe fiecare linie apoi cele unice stocate într-un SortedSet<T> sa fie look-upurile rapide(binary tree),câteva linii maxim in total. Ciudata combinatia de hash + binary tree. Merge (daca garantezi ca hashul e unic), dar se poate si mai bine & mai usor.
La ora asta nu stau sa-l fac mai bine, oricum, viteza e limitata de citirea de pe disc. Evident ca in productie nici nu se pune problema sa parsezi asa ip-uri ![]() Prea putina memorie alocata. PS: Vezi ca .NET iti ofera un mod mai usor de a enumera liniile din fisier. |
#22
Posted 07 April 2021 - 10:07

#23
Posted 07 April 2021 - 10:08

pai care ar fi diferenta daca parsezi ip-ul in loc de un hah sau utilizezi de exemplu un set normal fata de un sorted set? nu inteleg la ce te ajuta daca trebuia sa fie gata ieri ![]() |
#24
Posted 07 April 2021 - 10:08

#25
Posted 07 April 2021 - 10:17

la 20 GB fisier dezarhivat in 120 GB fisier text nici nu sughita prea tare sistemul. o sa dureze vreo 5-10 min pana il dezarhiveaza dar nu va crapa sistemul
am servere de test ce comprima loguri de 50 GB in fiecare zi. ideea e ca incarcarea datelor din fisierul de 120 GB sa se poata face fara sa scrape sistemul, apoi rezultatul sa poata fi iar stocat fara sa crape sistemul ptr ca teoretic sunt 2^32 ip-uri, adica 4,294,967,296 valori posibilie. daca incerci sa faci o structura care sa stocheze 4 miliarde inregistrari in memorie o sa crape |
#27
Posted 07 April 2021 - 10:38

daca incerci sa faci o structura care sa stocheze 4 miliarde inregistrari in memorie o sa crape Inregistrarile respective sunt 0 sau 1 in cazul asta, deci incap in vreo 500 MB memorie.
Hash-ul prin definitie este unic, o functie injectiva Hashul generic accepta intrari oricat de mari si scoate iesiri de o dimesiune fixa. Nu e nici unic nici injectiv.
ambele le ai deja implementate știi ca merg sigur Si alte structuri de date ai deja implementate in JDK/.NET/STL/etc.
Ideal ar sa ajungi la rezultat fara sa te complici inutil si sa adaugi gold-plating care poate sa nu mearga Nu te complici. Nu impui citirea dintr-un fisier text, citesti de pe standard input si atunci nu-ti mai pasa daca datele vin dintr-un fisier, dintr-o arhiva, de pe net sau poate-s chiar generate pe loc de un program de test. |
#28
Posted 07 April 2021 - 10:39

Hash-ul prin definitie este unic, o functie injectiva
sorted setu in spate e un binary tree lookupul e mai rapid decât un set normal, apoi xxHash e posibil sa fie cam pe acolo cu parsareaa. ambele le ai deja implementate știi ca merg sigur, termini mai repede tasku cu o siguranță mai mare pe implementare și mai repede decât dacă îți faci parsarea tu și calculezi indexu tu. |
|
#29
Posted 07 April 2021 - 10:45

În teorie, dar nu în lumea reală. în lumea reală aveam o infinitate de șiruri de caractere posibile, dar de exemplu în Java hash-ul poate reprezenta maxim 2^32. Mă îndoiesc. Binary tree înseamnă O(log(n)), set înseamnă O(1). Dacă n este suficient de mic și implementarea binary tree are constante suficient de mici, iar implementarea set are constate suficient de mari, atunci da, posibil să fie mai rapid să cauți în binary tree decât în set. |
#30
Posted 07 April 2021 - 11:57

Prea putina memorie alocata. PS: Vezi ca .NET iti ofera un mod mai usor de a enumera liniile din fisier. Quote It is necessary to calculate the number of unique IP addresses in this file, consuming as little memory and time as possible. Daca te referi la File.ReadLines, problema e ca nu poti sa-i specifici optiunile de la modul de deschidere a fisierului, in special parcurgerea secventiala. Mai e chestia evidenta ca citirea si prelucrarea ar trebui sa fie facute in paralel, dar sincer sa fiu mi-e cam lene. ![]() Quote A simple text file with IPv4 addresses is given. |
#32
Posted 07 April 2021 - 13:35

Nu inteleg ce vrei sa spui cu prea putina memorie? Pai asta e cerinta. Am citit aiurea, ca ai declara array de uint dar defapt era de ulong.
Daca te referi la File.ReadLines, problema e ca nu poti sa-i specifici optiunile de la modul de deschidere a fisierului, in special parcurgerea secventiala. O specifica ei https://referencesou...amreader.cs,240 |
#34
Posted 07 April 2021 - 14:13

sa postez si eu o implementare, probabil mai putin eficienta ca cea de mai sus ca viteza, dar am zis sa fie ceva diferit asa ca am incercat sa folosesc un fisier mapat in ram. ca sa mearga close-ul corect trebuie java >= 9
public class MemoryFile implements Closeable { private static final int MAPPING_SIZE = 1 << 30; private final RandomAccessFile raf; private final List<MappedByteBuffer> mappings = new ArrayList<>(); private long maxSize; private int elemSize = 1; private String fileName; public MemoryFile(String filename, long elements) throws IOException { this.fileName = filename; this.raf = new RandomAccessFile(filename, "rw"); this.maxSize = elements; try { long size = elemSize * elements; for (long offset = 0; offset < size; offset += MAPPING_SIZE) { long size2 = Math.min(size - offset, MAPPING_SIZE); mappings.add(raf.getChannel().map(FileChannel.MapMode.READ_WRITE, offset, size2)); } } catch (IOException e) { raf.close(); throw e; } } public byte get(long index) { assert index >= 0 && index < maxSize; long p = index * elemSize; int mapN = (int) (p / MAPPING_SIZE); int offN = (int) (p % MAPPING_SIZE); return mappings.get(mapN).get(offN); } public void set(long index, byte b) { assert index >= 0 && index < maxSize; long p = index * elemSize; int mapN = (int) (p / MAPPING_SIZE); int offN = (int) (p % MAPPING_SIZE); mappings.get(mapN).put(offN, b); } public void close() throws IOException { try { Class<?> unsafeClass = Class.forName("sun.misc.Unsafe"); Field unsafeField = unsafeClass.getDeclaredField("theUnsafe"); unsafeField.setAccessible(true); Object unsafe = unsafeField.get(null); Method invokeCleaner = unsafeClass.getMethod("invokeCleaner", ByteBuffer.class); for (MappedByteBuffer buffer : mappings) { invokeCleaner.invoke(unsafe, buffer); } raf.close(); new File(fileName).delete(); } catch (Exception e) { throw new RuntimeException(e); } } public static void main(String[] args) throws IOException { long start = System.currentTimeMillis(); long count = 0; long maxValue = 1l << 32; try (MemoryFile stuff = new MemoryFile("test.txt", 1L << 32)) { String zipFile = "ip_addresses.zip"; long lineRead = 0; try (ZipFile zf = new ZipFile(zipFile)) { ZipEntry ze = (ZipEntry) zf.entries().nextElement(); try (BufferedReader br = new BufferedReader(new InputStreamReader(zf.getInputStream(ze), StandardCharsets.UTF_8))) { for (String line = null; (line = br.readLine()) != null;) { lineRead++; if (lineRead % 10_000_000 == 0) { System.out.println("A citit= " + lineRead + ",unice pana acum=" + count); } long adress = Integer.toUnsignedLong(ByteBuffer.wrap(InetAddress.getByName(line).getAddress()).getInt()); if (stuff.get(adress) == 0) { count++; stuff.set(adress, (byte) 1); } if (count == maxValue) { break; } } } } System.out.println("Total linii citite " + lineRead + ", unice=" + count); } System.out.println("A durat " + (System.currentTimeMillis() - start)); } }LE implementarea mea citeste direct zip-ul la mine pe laptop a rulat in 26 de minute si a gasit unice 1000000000 si linii citite a raportat 8000000000 Edited by romio79, 07 April 2021 - 14:17. |
#35
Posted 07 April 2021 - 16:17

#36
Posted 08 April 2021 - 10:56

Anunturi
Bun venit pe Forumul Softpedia!
▶ 0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users