@furious programming nawet gdy w łańcuchu zamienię dane bez ozdobników - niepotrzebne dane Czas wykonywania Bedzie bardzo długo trwał nawet, gdy wyrzucę śmieci, Delphi i pascal nie radzi sobie z przetwarzaniem to samo przez to samo. 13 tyś zmiennych.I żadnego algorytmu mi nie polecicie, A wiesz dlaczego bo to pętla pod obciążeniem ,,,,
- 1
- 2

- Rejestracja:ponad 13 lat
- Ostatnio:około 4 godziny
- Lokalizacja:Tuchów
- Postów:12166
Mariusz Bruniewski napisał(a):
@furious programming nawet gdy w łańcuchu zamienię dane bez ozdobników - niepotrzebne dane Czas wykonywania Bedzie bardzo długo trwał nawet, gdy wyrzucę śmieci, […]
Te dane nie mają racji bytu, więc niepotrzebnie marnują miejsce na dysku — setki megabajtów, jeśli nie wiele gigabajtów. Cały czas mam wrażanie, że z jakiegoś powodu czerpiesz satysfakcję z zapychania dysku danymi — im więcej tym lepiej, bo lepiej brzmi, że masz pierdyliony linii w odcholerionach plików. Ty naprawdę myślisz, że im więcej tym lepiej? :D
Delphi i pascal nie radzi sobie z przetwarzaniem to samo przez to samo.
Chyba Ty. Jeśli nie umiesz napisać wydajnego algorytmu, to nie zwalaj winy na język.



- Rejestracja:około 4 lata
- Ostatnio:prawie 4 lata
- Postów:204
No i zrobiłem. Musiałem poszukać jakiś fajnych kolekcji. Znalazłem. Pierwszy raz w życiu użyłem tej klasy hashlisty. Ogólnie kod jest gówniany, sporo konkatenuje stringi, samo zapisywanie do pliku zabiera połowę czasu. Program działa ok 4-5 sek. Odpalam go w 1 wątku na 9 letnim laptopie. Na współczesnym sprzęcie, z szybszym dyskiem i odpalając parsowanie na n wątkach zejdzie się spokojnie poniżej 1s, a troszkę kod picując (chociażby ekstrakcja kluczy robię przechodząc o(n), ale nie wiem czy warunki nie zjadają czasu bo być może Pos() RPos() byłby szybszy, oraz zapis do pliku - można by to zrobić lepiej bez łączenia stringów przez + i splity), można by jeszcze więcej wycisnąć, ale nie chce mi się za free picować kodu dla kogoś, kto nie potrafi po polsku pisać. Chciałem kodu nie wrzucać tylko filmik, ale to chyba jeden sposób na udowodnienie racji i tego, że to nie Pascal jest problemem a czynnik między monitorem a fotelem. No i porównajcie objętość tego kodu, gdzie mój już jest sporo nadmiarowy i można by go skrócić. Dodatkowo dane testowe wygenerowałem więc powtórzenia są na niskim poziomie - po kilka powtórzeń. Im więcej powtarzalnych krotek to będzie się szybciej liczyło, więc mam zestaw testowy bardzo pesymistyczny.
Serio poniższy kod jest gówniany i CR bym nie przepuścił, ale nie ma sensu na potrzeby tego wątku robić refactoru prototypu.
...
type
TMap = specialize TGHashMapLP<string, Integer>;
...
function THolyGrail.ReadExtractKeysAndCountInMap: string;
var
i,j: integer;
openBracketPos, closeBracketPos, firstSpacePos, lastSpacePost : integer;
txtf,f: TextFile;
s: String;
s1,s2,s3,k : String;
values: TMap;
e: string;
rec: TStringArray;
begin
values := TMap.Create;
for i := 1 to 100 do
begin
AssignFile(txtf, IntToStr(i)+'.txt');
Reset(txtf);
while true do
begin
ReadLn(txtf, s) ;
if eof(txtf) then
begin
break;
end;
firstSpacePos := -1;
for j := 1 to 100 do
begin
if s[j]=' ' then
begin
if firstSpacePos = -1 then
begin
firstSpacePos := j;
end else begin
lastSpacePost := j;
end;
end else if s[j] = '[' then
begin
openBracketPos := j;
end else if s[j] = ']' then
begin
closeBracketPos := j;
end;
end;
s1 := Copy (s,1,firstSpacePos-1);
s2 := Copy (s,openBracketPos+1,closeBracketPos-openBracketPos-1);
s3 := Copy (s, lastSpacePost+1,Length(s)-lastSpacePost);
k:= s1 + ' ' + s2 + ' ' +s3;
if values.Contains(k) then
begin
values[k] := values[k]+1;
end else begin
values.Add(k,1);
end;
end;
Close(txtf);
end;
j := values.Count;
AssignFile(F, 'output.txt');
Rewrite(F);
for e in values.Keys do
begin
rec := e.Split (' ');
s1 := rec[0];
s2 := rec[1];
s3 := rec[2];
writeln(F, IntToStr(values.Items[e]) + ' - ' + rec[0] + ' razy wystąpiło powtórzenie w rzędzie [' + rec[1]+ '] => Powtórzenia liczb z sortowaniem pliki PLBS.txt Poz.: ' + rec[2]);
end;
CloseFile(F);
values.Destroy;
end;
screecast:
Tak więc weź sobie ten mój kod i dalej baw się w oszukiwanie się i granie w lotto. Jeśli natomiast chcesz po swojemu to koniecznie oczyszczaj ten shitowy format i używaj porządnych map do liczenia. TStringLiata jest gówniana. Podobnie TFPGMap. No i trzeba by to przekazać w jakimś streamie do dalszego przetwarzania albo zoptymalizować zapis do pliku.
btw. przez ten moment nieoptymalny kod napisany na kolanie zliczył 1,4mln linii. W pierwszych postach twierdziłeś, że miałeś problemy już z tysiącami...
kolejna edyta - zostały zmienne do debuggu, ale ich już nie usuwam.
- zliczanie.gif (3 MB) - ściągnięć: 13




while no EoF(Plik) do
— jest krótka i robi to co trzeba. :P

- Rejestracja:ponad 19 lat
- Ostatnio:około 3 lata
- Lokalizacja:Świecie
- Rejestracja:około 4 lata
- Ostatnio:prawie 4 lata
- Postów:204
A próbowałeś otworzyć w swojej solucji projektu perpetum tototlotkera, skąpilować i kliknąć dodaj do projektu ;) ?
- Rejestracja:około 4 lata
- Ostatnio:prawie 4 lata
- Postów:204
- screenshot-20210411110533.png (35 KB) - ściągnięć: 6

- Rejestracja:ponad 19 lat
- Ostatnio:około 3 lata
- Lokalizacja:Świecie
@pragmaticdev Ciekawi mnie Twój kod i za wszelką cenę chce go sprawdzić. TGHashMapLP
unit1.pas Error: Identifier not found "TGHashMapLP" Chce, aby kod działał nie w konsoli lecz w unicie.
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, LGenerics; // nawet gdy dodam tutaj LGenerics
type
TMap = specialize TGHashMapLP < string, Integer>;
- LG.jpg (27 KB) - ściągnięć: 10

- Rejestracja:ponad 19 lat
- Ostatnio:około 3 lata
- Lokalizacja:Świecie
- Rejestracja:około 4 lata
- Ostatnio:prawie 4 lata
- Postów:204
Ja cie... Przecież ja wczoraj też nie znałem tej bibliotek i i odpaliłem exampla, który tam jest. Wystarczy dodać uses lgHashMap ....


- Rejestracja:około 7 lat
- Ostatnio:prawie 4 lata
- Postów:227

- Rejestracja:ponad 19 lat
- Ostatnio:około 3 lata
- Lokalizacja:Świecie

- Rejestracja:około 4 lata
- Ostatnio:prawie 4 lata
- Postów:204
Czyli rozumiem, że udało Ci się wpiąć mój kod do Twojego programu i działa tak jak oczekiwałeś?


- Rejestracja:ponad 19 lat
- Ostatnio:około 3 lata
- Lokalizacja:Świecie
@pragmaticdev PROCES MYŚLENIA I WIARY.
Wyobraź sobie, że taka lina jest blisko Ziemi. Powiesz sobie przejdę po niej. A niech teraz ona będzie bardzo wysoko. Powiesz nie dam rady. Choć lina tak samo długa jak i gruba. To jest strach. Aby go przezwyciężyć niektórzy muszą mieć opaski na oczach. Być w zaślepieniu, aby otworzyć oczy, że wszystko jest możliwe!
Pierwsza tajemnica. WIARA.
=====================
Musisz mieć przekonanie w 100%, że to co chcesz uzyskać zaistnieje w realności. To może być zdrowie, stosunki partnerskie - polepszenie ich lub cokolwiek. To 100% musi być realne dla Ciebie. Wystarczy jedna chwila zwątpienia w to co wierzysz. Proces stwarzania jest bardzo osłabiony. Nie o 1% myśli np. myślisz cały czas pozytywnie a tylko jedna myśl przyszła negatywna w stosunku do 99% myśli pozytywnych. Ta jedna myśl jak myślicie ma tylko 1%. Oczywiście, że nie to ma co najmniej 50% osłabienia Twojej wiary. Taka jest prawda. Jedno zwątpienie zakłóca niesamowicie proces stwarzania, gdyż w tym momencie 1% myśli negatywnej podświadomość zaczyna przedstawiać Tobie kolejne warianty negatywności. Poprzez obrazy i wyobrażenia w podświadomości. Popatrz na poniższy obrazek i zauważ o co mi chodzi w przekazie.
- jaki.jpg (23 KB) - ściągnięć: 4
- Rejestracja:około 4 lata
- Ostatnio:prawie 4 lata
- Postów:204
Jak spadniesz z liny 30cm od ziemią to co najwyżej skręcisz kostkę. Jak spadniesz z 10m możesz się zabić lub zostać kaleką. Strach w tym przypadku jest racjonalny bo skutki niepowodzenia cięższe i nieuchronne. Z wiarą u mnie na bakier. Twardo stąpam po ziemi i kieruje się determinizmem. O ile zgodzę się, że konsekwencja i systematyka są potrzebne tak powinno się wybierać osiągalne cele i racjonalne metody. Jeśli ktoś pokazałby mi człowieka, który uczy się programować i kiepsko mu idzie i chce zacząć robić programy na zamówienie, zatrudnić się czy otworzyć jakiegoś SaaS to powiem, że przedsiębiorca, zaradny. Jak widzę takiego gościa co to robi by oszukać system liczbowy - powiem wariat. Nie istnieją żadne badania potwierdzające możliwość wykrycia klucza w grach liczbowych, przez fakt entropii. Równie dobrze możesz wierzyć, że kiedyś obudzisz się i wyrosną ci skrzela. Będziesz co dziennie moczył się w wodzie i doskonalił pływanie i mimo, że nie zwątpisz ani razy to prędzej się utopisz niż zostaniesz rybą. Nie chodzi o to, że wygrana jest nierealna - istnieje pewne małe aczkolwiek skonczone prawdopodobieństwo, że trafisz, ale to przez przypadek. Za to nierealnym jest stworzenie modelu, który powtarzalnie będzie przewidywał losowania. Jeśli taki jesteś pewien to zacznij od prostszych rzeczy - bez czujników wiatru, ciśnienia, dokładnej kamery tylko mając jakiś milion prób rzutu moneta opracuj sposób na przewidzenie czy wypadnie orzeł czy reszka. Potem bierz się, za bardziej skąplikowane gry.

- Rejestracja:ponad 19 lat
- Ostatnio:około 3 lata
- Lokalizacja:Świecie
@furious programming
Nie może nie działać — to wbudowana procedura. — @furious programming
- error.JPG (33 KB) - ściągnięć: 446
- Rejestracja:około 4 lata
- Ostatnio:prawie 4 lata
- Postów:204
@Mariusz Bruniewski: bo wołasz to z kodu formy pewnie i myśli że chodzi k Close z customformy. Zawołaj tam System.Close - ja nie używałem customformy i nie było konfliktu. Lub to CloseFile użyj.
Btw głupie jest walenie logiki bezpośrednio do kodu formy. Zrób jakies klasy z logiką, co implementują jakiś interface i wstrzykuje to do formy jakimś kontenerem. Chyba mormot ma jakieś DI. Wtedy unikniesz konfliktów z kodem form. No i masz mniejszy coupling i możliwość wymiany implementacji na szybszą/wolną/inna.


- Rejestracja:ponad 19 lat
- Ostatnio:około 3 lata
- Lokalizacja:Świecie
@pragmaticdev to teraz ja dziele się wiedzą.
- Mapa649.pdf (58 KB) - ściągnięć: 53
- Filtr649.pdf (82 KB) - ściągnięć: 53



- Rejestracja:ponad 19 lat
- Ostatnio:około 3 lata
- Lokalizacja:Świecie

- Rejestracja:ponad 19 lat
- Ostatnio:około 3 lata
- Lokalizacja:Świecie
- Rejestracja:około 4 lata
- Ostatnio:prawie 4 lata
- Postów:204
Ale Ty wiesz, że zastosowałeś dziedzinę 50x większą niż pierwotnie zakładałeś na początku tego wątku? Mówiłeś o 100 plikach po 14k lini to daje 1 400 000 linii. Potem gdzieś mówiłeś o 1000 plikach po 14k linii czyli już mamy 14 000 000 linii czyli 10x więcej. Jak masz 5 plików po 14kk linii to mamy już 70 000 000 linii czyli 50x więcej... Rozumiem, że potargałem Twoje ego, tym, że sądzę, że wymyślasz sobie rzeczywistość i Twoje posty to w połowie po prostu brednie, które nie są pisane po polsku... ale co byś nie zrobił, zwiększając dziedzinę testową, to czas wykonania algorytmu też będzie wzrastał...

- Rejestracja:około 4 lata
- Ostatnio:prawie 4 lata
- Postów:204
Natomiast jak coś działa Tobie wolno to wrzuć tutaj kod metody i proszę porównaj jego działania na tej samej co ja dziedzinie - czyli 100 plików po 14k linii. Inaczej nie jest to miarodajne, bo wzrost czasu nie jest tutaj liniowy.
- Rejestracja:około 4 lata
- Ostatnio:prawie 4 lata
- Postów:204
Nie umiesz używać komentarzy... Twój problem, który sam zdefiniowałeś to liczenie 100 plików z 14k liniami w czasie poniżej 1h. Ja zrobiłem algorytm co liczy to w kilka sekund ;p Chyba założenia są spełnione XD Pytanie też ile czasu liczyło się to Twoje 70mln wierszy bo teraz to tylko ściemniasz historyjki jakieś. Podaj dokładny czas. Ten kwestia, że to jakieś 7GB danych... czyli na przeciętnym SSD jakaś 1 minuta to będzie wczytywanie danych do pamięci, a też pytanie ile te kolekcje spuchną i ile masz ramu na komputerze testowym... Na pewno nie zrobisz algorytmu, którego dziedzina testowa będzie dążyć do nieskończoności, a czas wykonania będzie w granicy kilku sekund...

- Rejestracja:około 21 lat
- Ostatnio:około 3 lata
- Postów:227
Od lat nie pisałem w Delphi, ale postanowiłem, że sobie zrobię. Szybko okazało, że czytanie plików tekstowych w FPC jest bardzo wolne. I nie ma to za bardzo uzasadnienia, bo nawet klepnięty na szybko skrypt w Pythonie iterował szybciej. Ostatecznie zaimplementowałem to na Streamach. Przy okazji odpaliły mi się znajome neurony, więc możliwe, że już to kiedyś robiłem. Tak że, ten, wygenerowałem 5 plików po 14 milionów linii w podanym wyżej formacie, gdzie pierwsza wartość to losowa liczba z zakresu 1..6, a druga to 1..50000. Odpaliłem to 6-rdzeniowym procesorze, więc żaden wątek nie był przygłodzony i program zliczył wszystko w 4 sekundy. Czyli każdy wątek przerobił ok. 360MB danych w sekundę.
program LottoDestroyer;
{$mode objfpc}
uses
Classes, SysUtils;
const
MAX_ROW = 6;
MAX_POSITION = 50000;
FILE_COUNT = 5;
CHUNK_SIZE = 1024 * 1024;
type
TFileCruncher = class(TThread)
constructor Create(Filename: String);
procedure Execute; override;
public
Counts: Array[1..MAX_POSITION, 1..MAX_ROW] of Integer;
private
Filename: String;
end;
constructor TFileCruncher.Create(Filename: String);
begin
inherited Create(True);
self.Filename := Filename;
end;
procedure TFileCruncher.Execute;
var
Handler: TFileStream;
Row, Position: Integer;
Buffer: Array[1..CHUNK_SIZE] of Char;
Bytes: LongInt;
Digits: Array[1..8] of Char;
InNumber: Boolean;
Counter: Integer;
i: Integer;
begin
Handler := TFileStream.Create(Self.FileName, fmOpenRead);
repeat
Bytes := Handler.Read(Buffer, Length(Buffer));
for i := 1 to Bytes do
begin
if Buffer[i] = ']' then
begin
InNumber := False;
Val(Copy(Digits, 1, Counter-1), Row);
end;
if Buffer[i] = #10 then
begin
InNumber := False;
Val(Copy(Digits, 1, Counter-1), Position);
Inc(Self.Counts[Position][Row]);
end;
if InNumber and (Ord(Buffer[i]) >= 48) and (Ord(Buffer[i]) <= 57) then
begin
Digits[Counter] := Buffer[i];
Inc(Counter);
end;
if Buffer[i] = '[' then
begin
InNumber := True;
Counter := 1;
end;
if Buffer[i] = ':' then
begin
InNumber := True;
Counter := 1;
end;
end;
until Bytes < Length(Buffer)
end;
var
Threads: Array[1..FILE_COUNT] of TFileCruncher;
Start: Double;
i, j, k: Integer;
Counts: Array[1..MAX_POSITION, 1..MAX_ROW] of Integer;
begin
Start := Now;
for i := 1 to FILE_COUNT do
begin
Threads[i] := TFileCruncher.Create(IntToStr(i) + '.txt');
Threads[i].Start;
end;
for i := 1 to FILE_COUNT do Threads[i].waitFor;
for i := 1 to FILE_COUNT do
begin
for j := 1 to MAX_POSITION do
begin
for k := 1 to MAX_ROW do
begin
Counts[j][k] := Counts[j][k] + Threads[i].Counts[j][k];
end;
end;
end;
Writeln(Counts[6][4]);
Writeln(Format('%7.2f', [(Now - Start) * 100000]));
end.
Poza tym kisnę z tego deklarowania zmiennych przed kodem :D





- Rejestracja:ponad 13 lat
- Ostatnio:około 4 godziny
- Lokalizacja:Tuchów
- Postów:12166
szatkus napisał(a):
Od lat nie pisałem w Delphi, ale postanowiłem, że sobie zrobię. Szybko okazało, że czytanie plików tekstowych w FPC jest bardzo wolne. I nie ma to za bardzo uzasadnienia […]
IMO jest — ReadLn
czyta bajt po bajcie, co w żadnym wypadku nie jest wydajne. ;)
Poza tym kisnę z tego deklarowania zmiennych przed kodem :D
A widzisz, w Delphi można deklarować zmienne jak w C (czyli wszędzie), a we Free Pascalu nie.
I był czas, że pytałem deweloperów kompilatora, czy są plany dotyczące dodania wsparcia dla deklaracji stałych i zmiennych wewnątrz bloków kodu (w końcu FPC jest silnie kompatybilny z Delphi), ale zaczęło się jęczenie użytkowników, że „to takie niepascalowe”, że to „zniszczy czytelność kodu” i tego typu banialuki. Ostatecznie nazwałem ich zamrożonymi w przeszłości „dinozaurami hamującymi rozwój”, ci się obrazili, a wsparcia zmiennych jak nie było tak nie ma i nie zanosi się na to, że kiedykolwiek będzie (dla mnie to bardzo wielka szkoda).
Chociaż tyle dobrze, że trwają prace nad dodaniem wsparcia metod anonimowych. :D





- Rejestracja:około 4 lata
- Ostatnio:prawie 4 lata
- Postów:204
Wydaje mi się że żadna ilość wydajnych implementacji nie przekona autora, że to się da zrobić. Btw - gdzie Twój test z 8GB? Ile to czasu liczy ;) ?
- Rejestracja:około 21 lat
- Ostatnio:około 2 miesiące
- Postów:1082
szatkus napisał(a):
Poza tym kisnę z tego deklarowania zmiennych przed kodem :D
To Ty się na Delphi nie znasz, bo można np. tak:
for var i := 1 to Bytes do
Także ten, kisnę z Twojego kiśnięcia, cokolwiek to znaczy ;-)




- Rejestracja:ponad 19 lat
- Ostatnio:około 3 lata
- Lokalizacja:Świecie
@wloochacz: sprawdzę i dam znać.
- 1
- 2
szatkus