Commit 09a290b3 by Patryk Czarnik

Przykłady sprzedaz dot. wydajności

parent d633cd63
package sprzedaz.wydajnosc;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class MaszynaWczytujaca {
private final Map<String, LocalDate> pulaDat = new ConcurrentHashMap<>();
private final Map<String, BigDecimal> pulaCen = new ConcurrentHashMap<>();
public Transakcja wczytajJedenRekord(String linia) {
String[] pola = linia.split(",");
int sztuk = Integer.parseInt(pola[6]);
LocalDate data = pulaDat.computeIfAbsent(pola[0], LocalDate::parse);
BigDecimal cena = pulaCen.computeIfAbsent(pola[5], BigDecimal::new);
String miasto = pola[1].intern();
String sklep = pola[2].intern();
String kategoria = pola[3].intern();
String towar = pola[4].intern();
return new Transakcja(data, miasto, sklep, kategoria, towar, cena, sztuk);
}
public static List<Transakcja> wczytajCalyPlik(File plik) throws IOException {
MaszynaWczytujaca maszynaWczytujaca = new MaszynaWczytujaca();
List<Transakcja> lista = new ArrayList<>();
try(BufferedReader reader = Files.newBufferedReader(plik.toPath())) {
String linia;
while ((linia = reader.readLine()) != null) {
Transakcja transakcja = maszynaWczytujaca.wczytajJedenRekord(linia);
lista.add(transakcja);
}
}
return lista;
}
}
package sprzedaz.wydajnosc;
import java.util.Objects;
public class Opakowanie<T> {
private T value;
private Opakowanie(T v) {
this.value = v;
}
public static <T> Opakowanie<T> empty() {
return new Opakowanie<T>(null);
}
public static <T> Opakowanie<T> of(T value) {
return new Opakowanie<T>(value);
}
public T get() {
return value;
}
public void set(T value) {
this.value = value;
}
@Override
public String toString() {
return "{" + String.valueOf(value) + "}";
}
@Override
public int hashCode() {
return Objects.hash(value);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Opakowanie other = (Opakowanie) obj;
return Objects.equals(value, other.value);
}
}
package sprzedaz.wydajnosc;
import java.util.function.Function;
public class Pomiary {
public static void zmierzCzasDzalania(Runnable runnable) {
long p = System.currentTimeMillis();
runnable.run();
long k = System.currentTimeMillis();
System.out.printf("t = %d\n", k - p);
}
public static void zmierzCzasDzalaniaRepeat(final Runnable runnable, final int repeat) {
long p = System.currentTimeMillis();
for(int i = 0; i < repeat; i++) {
runnable.run();
}
long k = System.currentTimeMillis();
System.out.printf("t = %d\n", k - p);
}
public static <T,R> void zmierzCzasDzalania(Function<T, R> funkcja, T arg) {
long p = System.currentTimeMillis();
Object res = funkcja.apply(arg);
long k = System.currentTimeMillis();
System.out.printf("t = %d\n", k - p);
}
public static void zmierzCzasDzalaniaIntString(Function<Integer, String> metoda, int n) {
long p = System.currentTimeMillis();
String str = metoda.apply(n);
long k = System.currentTimeMillis();
System.out.printf("n = %d, len = %d, t = %d\n", n, str.length(), k-p);
}
public static void wypiszPamiec() {
Runtime runtime = Runtime.getRuntime();
long used = (runtime.totalMemory() - runtime.freeMemory()) >> 20;
long total = runtime.totalMemory() >> 20;
System.out.printf("zajęta pamięć: %5d MB\n", used);
System.out.printf("cała pamięć: %5d MB\n", total);
}
}
package sprzedaz.wydajnosc;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Objects;
public class Transakcja {
private LocalDate data;
private String miasto;
private String sklep;
private String kategoria;
private String towar;
private BigDecimal cena;
private int sztuk;
public Transakcja() {
}
public Transakcja(LocalDate data, String miasto, String sklep, String kategoria, String towar, BigDecimal cena, int sztuk) {
this.data = data;
this.miasto = miasto;
this.sklep = sklep;
this.kategoria = kategoria;
this.towar = towar;
this.cena = cena;
this.sztuk = sztuk;
}
public LocalDate getData() {
return data;
}
public void setData(LocalDate data) {
this.data = data;
}
public String getMiasto() {
return miasto;
}
public void setMiasto(String miasto) {
this.miasto = miasto;
}
public String getSklep() {
return sklep;
}
public void setSklep(String sklep) {
this.sklep = sklep;
}
public String getKategoria() {
return kategoria;
}
public void setKategoria(String kategoria) {
this.kategoria = kategoria;
}
public String getTowar() {
return towar;
}
public void setTowar(String towar) {
this.towar = towar;
}
public BigDecimal getCena() {
return cena;
}
public void setCena(BigDecimal cena) {
this.cena = cena;
}
public int getSztuk() {
return sztuk;
}
public void setSztuk(int sztuk) {
this.sztuk = sztuk;
}
public BigDecimal getWartosc() {
return cena.multiply(BigDecimal.valueOf(sztuk));
}
public long getWartoscLong() {
return cena.movePointRight(2).longValue() * sztuk;
}
public double getWartoscDouble() {
return cena.doubleValue() * sztuk;
}
@Override
public int hashCode() {
return Objects.hash(cena, data, kategoria, miasto, sklep, sztuk, towar);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Transakcja other = (Transakcja) obj;
return Objects.equals(cena, other.cena) && Objects.equals(data, other.data)
&& Objects.equals(kategoria, other.kategoria) && Objects.equals(miasto, other.miasto)
&& Objects.equals(sklep, other.sklep) && sztuk == other.sztuk && Objects.equals(towar, other.towar);
}
@Override
public String toString() {
return "Rekord [data=" + data + ", miasto=" + miasto + ", sklep=" + sklep + ", kategoria="
+ kategoria + ", towar=" + towar + ", cena=" + cena + ", sztuk=" + sztuk + "]";
}
}
package sprzedaz.wydajnosc;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
// Wersja ze Scanner, split i LinkedList - działa najwolniej
public class WczytajSprzedaz1 {
static List<Transakcja> wczytaj(File plik) throws IOException {
List<Transakcja> lista = new LinkedList<>();
try (Scanner sc = new Scanner(plik)) {
//sc.nextLine();
while (sc.hasNextLine()) {
String linia = sc.nextLine();
String[] pola = linia.split(",");
LocalDate data = LocalDate.parse(pola[0]);
String miasto = pola[1];
String sklep = pola[2];
String kategoria = pola[3];
String towar = pola[4];
BigDecimal cena = new BigDecimal(pola[5]);
int sztuk = Integer.parseInt(pola[6]);
Transakcja transakcja = new Transakcja(data, miasto, sklep, kategoria, towar, cena, sztuk);
lista.add(transakcja);
}
}
return lista;
}
public static void main(String[] args) {
Pomiary.wypiszPamiec();
Opakowanie<List<Transakcja>> wynik = Opakowanie.empty();
System.out.println("\nczytam");
// File plik = new File("rekordy.txt");
File plik = new File("sprzedaz_100.csv");
Pomiary.zmierzCzasDzalania(() -> {
try {
List<Transakcja> lista = wczytaj(plik);
wynik.set(lista); // aby GC nie usunął listy
System.out.println("Wczytano " + lista.size());
} catch (IOException e) {
e.printStackTrace();
}
});
Pomiary.wypiszPamiec();
System.out.println("\ngc");
System.gc();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
Pomiary.wypiszPamiec();
System.out.println(wynik.get().size());
}
}
package sprzedaz.wydajnosc;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.LinkedList;
import java.util.List;
// Wersja używająca BufferedReader zamiast Scanner - działa szybciej
public class WczytajSprzedaz2 {
static List<Transakcja> wczytaj(File plik) throws IOException {
List<Transakcja> lista = new LinkedList<>();
// try(BufferedReader reader = Files.newBufferedReader(plik.toPath())) {
try(BufferedReader reader = new BufferedReader(new FileReader(plik)) ) {
String linia;
while ((linia = reader.readLine()) != null) {
String[] pola = linia.split(",");
LocalDate data = LocalDate.parse(pola[0]);
String miasto = pola[1];
String sklep = pola[2];
String kategoria = pola[3];
String towar = pola[4];
BigDecimal cena = new BigDecimal(pola[5]);
int sztuk = Integer.parseInt(pola[6]);
Transakcja transakcja = new Transakcja(data, miasto, sklep, kategoria, towar, cena, sztuk);
lista.add(transakcja);
}
}
return lista;
}
public static void main(String[] args) {
Pomiary.wypiszPamiec();
Opakowanie<List<Transakcja>> wynik = Opakowanie.empty();
System.out.println("\nczytam");
File plik = new File("sprzedaz_100.txt");
Pomiary.zmierzCzasDzalania(() -> {
try {
List<Transakcja> lista = wczytaj(plik);
wynik.set(lista); // aby GC nie usunął listy
System.out.println("Wczytano " + lista.size());
} catch (IOException e) {
e.printStackTrace();
}
});
Pomiary.wypiszPamiec();
System.out.println("\ngc");
System.gc();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
Pomiary.wypiszPamiec();
System.out.println(wynik.get().size());
}
}
package sprzedaz.wydajnosc;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
// Wersja używająca ArrayList zamiast LinkedList - działa szybciej
public class WczytajSprzedaz3 {
static List<Transakcja> wczytaj(File plik) throws IOException {
List<Transakcja> lista = new ArrayList<>();
try(BufferedReader reader = Files.newBufferedReader(plik.toPath())) {
String linia;
while ((linia = reader.readLine()) != null) {
String[] pola = linia.split(",");
LocalDate data = LocalDate.parse(pola[0]);
String miasto = pola[1];
String sklep = pola[2];
String kategoria = pola[3];
String towar = pola[4];
BigDecimal cena = new BigDecimal(pola[5]);
int sztuk = Integer.parseInt(pola[6]);
Transakcja transakcja = new Transakcja(data, miasto, sklep, kategoria, towar, cena, sztuk);
lista.add(transakcja);
}
}
return lista;
}
public static void main(String[] args) {
Pomiary.wypiszPamiec();
Opakowanie<List<Transakcja>> wynik = Opakowanie.empty();
System.out.println("\nczytam");
File plik = new File("sprzedaz_100.csv");
Pomiary.zmierzCzasDzalania(() -> {
try {
List<Transakcja> lista = wczytaj(plik);
wynik.set(lista); // aby GC nie usunął listy
System.out.println("Wczytano " + lista.size());
} catch (IOException e) {
e.printStackTrace();
}
});
Pomiary.wypiszPamiec();
System.out.println("\ngc");
System.gc();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
Pomiary.wypiszPamiec();
System.out.println(wynik.get().size());
}
}
package sprzedaz.wydajnosc;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
// Wersja wprowadzająca pomysł puli obiektów - drobna poprawa wydajności.
public class WczytajSprzedaz4 {
static List<Transakcja> wczytaj(File plik) throws IOException {
Map<String, LocalDate> pulaDat = new HashMap<>();
Map<String, BigDecimal> pulaCen = new HashMap<>();
List<Transakcja> lista = new ArrayList<>();
try(BufferedReader reader = Files.newBufferedReader(plik.toPath())) {
String linia;
while ((linia = reader.readLine()) != null) {
String[] pola = linia.split(",");
LocalDate data = pulaDat.get(pola[0]);
if(data == null) {
data = LocalDate.parse(pola[0]);
pulaDat.put(pola[0], data);
}
BigDecimal cena = pulaCen.get(pola[5]);
if(cena == null) {
cena = new BigDecimal(pola[5]);
pulaCen.put(pola[5], cena);
}
String miasto = pola[1];
String sklep = pola[2];
String kategoria = pola[3];
String towar = pola[4];
int sztuk = Integer.parseInt(pola[6]);
Transakcja transakcja = new Transakcja(data, miasto, sklep, kategoria, towar, cena, sztuk);
lista.add(transakcja);
}
}
return lista;
}
public static void main(String[] args) {
Pomiary.wypiszPamiec();
Opakowanie<List<Transakcja>> wynik = Opakowanie.empty();
System.out.println("\nczytam");
File plik = new File("sprzedaz_100.csv");
Pomiary.zmierzCzasDzalania(() -> {
try {
List<Transakcja> lista = wczytaj(plik);
wynik.set(lista); // aby GC nie usunął listy
System.out.println("Wczytano " + lista.size());
} catch (IOException e) {
e.printStackTrace();
}
});
Pomiary.wypiszPamiec();
System.out.println("\ngc");
System.gc();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
Pomiary.wypiszPamiec();
System.out.println(wynik.get().size());
}
}
package sprzedaz.wydajnosc;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/* Naważniejsza rzecz - w tej wersji korzystamy ze String.intern()
Każdy wczytywany z pliku napis zamieniamy na napis o tej samej treści "z puli".
JVM utrzymuje pulę Stringów używanych przez aplikację.
Dla każdego napisu można odnaleźć odpowiadający mu napis z puli - wszystkie wystąpienia tego samego napisu
(np. "Warszawa") zostaną zastąpione odwołaniami do TEGO SAMEGO obiektu w pamięci.
Dzięki temu po wczytaniu dane zajmują mniej pamięci, GC ma mniej roboty, szybciej działa porównywanie napisów (a co za tym idzie np. HashMapa).
*/
public class WczytajSprzedaz5 {
static List<Transakcja> wczytaj(File plik) throws IOException {
Map<String, LocalDate> pulaDat = new HashMap<>();
Map<String, BigDecimal> pulaCen = new HashMap<>();
List<Transakcja> lista = new ArrayList<>();
try(BufferedReader reader = Files.newBufferedReader(plik.toPath())) {
String linia;
while ((linia = reader.readLine()) != null) {
String[] pola = linia.split(",");
int sztuk = Integer.parseInt(pola[6]);
LocalDate data = pulaDat.get(pola[0]);
if(data == null) {
data = LocalDate.parse(pola[0]);
pulaDat.put(pola[0], data);
}
BigDecimal cena = pulaCen.get(pola[5]);
if(cena == null) {
cena = new BigDecimal(pola[5]);
pulaCen.put(pola[5], cena);
}
String miasto = pola[1].intern();
String sklep = pola[2].intern();
String kategoria = pola[3].intern();
String towar = pola[4].intern();
Transakcja transakcja = new Transakcja(data, miasto, sklep, kategoria, towar, cena, sztuk);
lista.add(transakcja);
}
}
return lista;
}
public static void main(String[] args) {
Pomiary.wypiszPamiec();
Opakowanie<List<Transakcja>> wynik = Opakowanie.empty();
System.out.println("\nczytam");
File plik = new File("sprzedaz_100.csv");
Pomiary.zmierzCzasDzalania(() -> {
try {
List<Transakcja> lista = wczytaj(plik);
wynik.set(lista); // aby GC nie usunął listy
System.out.println("Wczytano " + lista.size());
} catch (IOException e) {
e.printStackTrace();
}
});
Pomiary.wypiszPamiec();
System.out.println("\ngc");
System.gc();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
Pomiary.wypiszPamiec();
System.out.println(wynik.get().size());
}
}
package sprzedaz.wydajnosc;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class WczytajSprzedaz6 {
static List<Transakcja> wczytaj(File plik) throws IOException {
Map<String, LocalDate> pulaDat = new ConcurrentHashMap<>();
Map<String, BigDecimal> pulaCen = new ConcurrentHashMap<>();
List<Transakcja> lista = new ArrayList<>();
try(BufferedReader reader = Files.newBufferedReader(plik.toPath())) {
String linia;
while ((linia = reader.readLine()) != null) {
String[] pola = linia.split(",");
int sztuk = Integer.parseInt(pola[6]);
LocalDate data = pulaDat.computeIfAbsent(pola[0], LocalDate::parse);
BigDecimal cena = pulaCen.computeIfAbsent(pola[5], BigDecimal::new);
String miasto = pola[1].intern();
String sklep = pola[2].intern();
String kategoria = pola[3].intern();
String towar = pola[4].intern();
Transakcja transakcja = new Transakcja(data, miasto, sklep, kategoria, towar, cena, sztuk);
lista.add(transakcja);
}
}
return lista;
}
public static void main(String[] args) {
Pomiary.wypiszPamiec();
Opakowanie<List<Transakcja>> wynik = Opakowanie.empty();
System.out.println("\nczytam");
File plik = new File("sprzedaz_100.csv");
Pomiary.zmierzCzasDzalania(() -> {
try {
List<Transakcja> lista = wczytaj(plik);
wynik.set(lista); // aby GC nie usunął listy
System.out.println("Wczytano " + lista.size());
} catch (IOException e) {
e.printStackTrace();
}
});
Pomiary.wypiszPamiec();
System.out.println("\ngc");
System.gc();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
Pomiary.wypiszPamiec();
System.out.println(wynik.get().size());
}
}
package sprzedaz.wydajnosc;
import java.io.File;
import java.io.IOException;
import java.util.List;
// Wydzielenie wczytywaia do oddzielnej klasy MaszynaWczytujaca.
// W tamtej klasie zamiast HashMap używany jest ConcurrentHashMap. Używam tam też nowych operacji na mapach - computeIfAbsent.
public class WczytajSprzedaz7 {
public static void main(String[] args) {
Pomiary.wypiszPamiec();
Opakowanie<List<Transakcja>> wynik = Opakowanie.empty();
System.out.println("\nczytam");
File plik = new File("sprzedaz_100.txt");
Pomiary.zmierzCzasDzalania(() -> {
try {
List<Transakcja> lista = MaszynaWczytujaca.wczytajCalyPlik(plik);
wynik.set(lista); // aby GC nie usunął listy
System.out.println("Wczytano " + lista.size());
} catch (IOException e) {
e.printStackTrace();
}
});
Pomiary.wypiszPamiec();
System.out.println("\ngc");
System.gc();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
Pomiary.wypiszPamiec();
System.out.println(wynik.get().size());
}
}
package sprzedaz.wydajnosc;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
public class WyczarujPliki {
public static void main(String[] args) {
try {
List<String> linie = Files.readAllLines(Paths.get("sprzedaz.csv"));
linie.remove(0);
for(int n : new int[]{1, 10, 100}) {
String plik = "sprzedaz_"+n+".csv";
System.out.println(plik);
zapiszPowielone(linie, n, new File(plik));
}
System.out.println("Gotowe");
} catch (IOException e) {
e.printStackTrace();
}
}
private static void zapiszPowielone(List<String> linie, int n, File file) throws FileNotFoundException {
try(PrintWriter out = new PrintWriter(file)) {
for(int tura = 0; tura < n; tura ++) {
for (String linia : linie) {
out.println(linia);
}
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment