Aktualizace:
- update: výsledky
- update6: Tomáš Kořínek
- update5: J. Jelínek a jeho třetí pokus.
- update4: aktualizace pořadí, změna na možnost 3 řešení, průběžné výsledky jsou zpět
- update3: podle návrhu udělím i cenu za nejoriginálnější řešení - i když nebude nejrychlejší - něco jako minule cena poroty. Jako podporu pro zasílání i krapet pomalejších řešení.
- update2: další soutěžící
- update: vylepšené měření, můj druhý pokus, dva další soutěžící
Od minulé soutěže mi už otrnulo a jelikož převážná většina lidí v anketě nebyla proti dalšímu kolu soutěže a do jara ještě chvilku máme čas, je zde další úkol.
Proti minulému kolu jsem změnil několik pravidel:
- je možno použít libovolný kompilátor pascalu (Delphi 2 - Delphi XE, FreePascal, ohledně C++Builderu zatím nevím zda by byl zájem)
- testované budou výsledné Vámi přeložené aplikace (minule jen jedna obsahující všechny řešení), zdrojový kód je jen pro kontrolu vítězů
- průběžně budou zveřejňovány přeložené aplikace, zaslané zdrojové kódy budou zveřejněny nakonec
- výsledné pořadí bude určeno během na 2 jádrovém Core 2 Duo (Thinkpad R400) na XP SP3
- v případě stejných výsledků rozhoduje zajímavější řešení, rozhodne porota ve složení Já, Já a Já
- můžu se tím pádem zúčastnit i já (bez nároku na výhru - doufám, že skončím aspoň v první polovině pole)
- co se bude dít mezi označenými místy kódu je úplně na Vás - dostanete vstupní data a na výstupu musí být naplněno pole počtů. Můžete použít i vlákna nebo si předat vhodně data. Žádná pravidla. Jen musí být data vypočítána programem (výsledný běh bude nad kapánek jinými daty)
- Pro určení pořadí bude rozhodující minimální čas ze 40 vyvolání soutěžní části programu. Při každém vyvolání musí být výsledky vypočítány samostatně bez návaznosti na předchozí nebo následující výpočty. Výpočty z různých vyvolání nemohou běžet paralelně. Opakované vyvolání je jen pro zpřesnění měření a program se musí chovat stejně i při pouhém jednom opakovaní.
- lze poslat max. 3 řešení (změna: dříve bylo 2 řešení)
- není povoleno manipulování s měřením času (jako přeprogramování časovače, patchnutí volání API funkce atd.)
- program dávající špatné výsledky je vyřazen
- konec 28.2.2011 ve 22:00 (tj. tři týdny)
- na výhru není právní nárok :-)
Doufám, že se pobavíte stejně jako já.
Zadání
Níže uvedený program vygeneruje testovací data (nejsou to ale data, která budou použita pro výsledný test) - jejich velikost zhruba odpovídá, formát bude přesně stejný. Jedná se o textový neunicode soubor, obsahující na každém řádku (konec řádku je CRLF) jeden z 20 tagů, případně jeho ukončovací variantu. Ukončovací varianta, tj. </xxxxxxx se bude ignorovat a nezapočítává se do výsledku.
generator.zip - program pro vygenerovaní vstupních dat - generování trvá několik sekund :-D
Ukázka výsledného souboru:
</body>
</strong>
<li>
</ul>
<div>
<head>
<head>
</head>
<td>
</em>
</html>
</tr>
Cílem je do připraveného pole spočítat jednotlivé výskyty.
- Ukončovací varianta, tj. </xxxxxxx se bude ignorovat a nezapočítává se do výsledku.
- Je garantováno, že nejsou jiné než povolené řetězce, tj. obsahem vstupního souboru je jen povolená množina tagů. (viz. řádky 15 - 18), můžete na to spoléhat (viz generátor).
- Základní kostra pro pascal je součástí zadání (sorry pro uživatele C++Builderu, ale pokud se chcete zúčastnit, můžete mi poslat kostru pro C++Builder)
Např. v uvedeném příkladu se bude jako první počítat <li>.
kostra.zip - základní program, zajistí načtení dat z data.bin (získáno generátorem nebo ručně), výpočet času a výpis výsledků. Mezi řádky 34 a 38 je Vaše hrací pole. Výsledek bude v aiCount, nulování není kostrou zaručeno. asData je množina povolených tagů, jejich pořadí a texty se nesmí a nebudou měnit, tj. můžete na to spoléhat.
Na návrh diskutujících (Pepák a anonym) byla upravena kostra - používá se nyní QueryPerformanceCounter a minimum ze 40 běhů.
1program Soutez;
2
3
4
5
6
7
8uses
9 Sysutils,
10 windows,
11 classes;
12
13const
14 ciCount = 20;
15 asData : array [1..ciCount] of string =
16 ('<body>', '<head>', '<html>', '<p>', '<table>', '<li>', '<ul>', '<div>', '<img>',
17 '<td>','<tr>', '<h1>', '<h2>', '<h3>', '<h4>', '<a>', '<em>', '<strong>',
18 '<code>', '<pre>');
19var
20 aiCount: array [1..ciCount] of integer;
21
22
23const
24 LOOP_COUNT = 40;
25var
26 pData: PByteArray;
27 f: TFileStream;
28 tick, tickend, frequency: Int64;
29
30 sOut:string;
31 x: Integer;
32 Loops: integer;
33 CurTime, TotalTime, MaxTime, MinTime: DWORD;
34begin
35 f:= TFileStream.Create('data.bin', fmOpenRead );
36 try
37 GetMem(pData, f.Size);
38 f.Read(pData^, f.Size);
39 TotalTime := 0;
40 MaxTime := 0;
41 MinTime := $ffffffff;
42 for Loops := 1 to LOOP_COUNT do
43 begin
44 QueryPerformanceFrequency(frequency);
45
46 QueryPerformanceCounter(tick);
47
48
49
50
51 QueryPerformanceCounter(tickend);
52
53 CurTime := Round(1000*(tickend - tick)/frequency);
54 Inc(TotalTime, CurTime);
55 if CurTime < MinTime then
56 MinTime := CurTime;
57 if CurTime > MaxTime then
58 MaxTime := CurTime;
59 end;
60 writeln(format('Autor: Radek Červinka, kompilator:%f', [CompilerVersion]));
61
62 writeln(Format('Last time = [%d]', [CurTime]));
63 writeln(Format('Min time = [%d], Average time = [%d], Max time = [%d]',
64 [MinTime, TotalTime div LOOP_COUNT, MaxTime]));
65 for x := 1 to 20 do
66 Writeln(Format('%s = %d', [asData[x], aiCount[x]]));
67
68 FreeMem(pData);
69 finally
70 FreeAndNil(f);
71 end;
72end.
Ceny
Hraje se na první místo dle času výpočtu. Pokud by se náhodou nedejbože stalo, že bych byl první (čemu ale opravdu nevěřím), cenu dle svého výběru získává druhý v pořadí.
Výběr je následující (jedna z variant + PDF verzi delphi.cz):
- 3x hrneček s logem Borland (archeologické kousky - ale je opravdu kvalitní a má tu správnou velikost na kafe - ideální do výbavy pro manželství)
- nebo vázanou knihu Delphi v kostce (1-5) (úplně nová)
- nebo epesní šiltovka s logem Embarcadero a uvedený hrneček


Poznámky
Osobně jsem použil Delphi 2007, v této úloze generuje zhruba stejně rychlý kód jako Delphi XE, jen je výsledné exe kratší.
Výsledné exe + zdrojové kódy mi zašlete a já Vám potvrdím přijetí. Pro antivirový test můžete použít virusscan.jotti.org.
Pořadí
Pro informaci: měření jsou na mém Core2Duo T8100 @ 2.10GHz.
Program očekává v adresáři patřičné vstupní data - viz generator.zip.
Výsledky jsou v samostatném článku.