Delphi.cz

Český portál Delphi

Optimalizační soutěž č.2

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ů.

program Soutez;
{$APPTYPE CONSOLE}
{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
{$STRINGCHECKS OFF}
{$INLINE ON}
{$O+}
{$R-}
uses
  Sysutils,
  windows,
  classes;

const
  ciCount = 20;
  asData : array [1..ciCount] of string =
  ('<body>', '<head>', '<html>', '<p>', '<table>', '<li>', '<ul>', '<div>', '<img>',   //9
   '<td>','<tr>', '<h1>', '<h2>', '<h3>', '<h4>', '<a>', '<em>', '<strong>',
   '<code>', '<pre>');    //20
var
  aiCount: array [1..ciCount] of integer;


const
  LOOP_COUNT = 40;
var
  pData: PByteArray;
  f: TFileStream;
  tick, tickend, frequency: Int64;

  sOut:string;
  x: Integer;
  Loops: integer;
  CurTime, TotalTime, MaxTime, MinTime: DWORD;
begin
  f:= TFileStream.Create('data.bin', fmOpenRead );
  try
    GetMem(pData, f.Size);
    f.Read(pData^, f.Size);
    TotalTime := 0;
    MaxTime := 0;
    MinTime := $ffffffff;
    for Loops := 1 to LOOP_COUNT do
    begin
      QueryPerformanceFrequency(frequency);

      QueryPerformanceCounter(tick);
// zacatek souteze, predavani je zalezitosti programatora
   // v pData jsou data
   // zde si muzete hrat

      QueryPerformanceCounter(tickend);
// konec souteze
      CurTime := Round(1000*(tickend - tick)/frequency);
      Inc(TotalTime, CurTime);
      if CurTime < MinTime then
        MinTime := CurTime;
      if CurTime > MaxTime then
        MaxTime := CurTime;
    end;
    writeln(format('Autor: Radek Červinka,  kompilator:%f', [CompilerVersion]));

    writeln(Format('Last time = [%d]', [CurTime]));
    writeln(Format('Min time = [%d], Average time = [%d], Max time = [%d]',
      [MinTime, TotalTime div LOOP_COUNT, MaxTime]));
    for x := 1 to 20 do
      Writeln(Format('%s = %d', [asData[x], aiCount[x]]));

    FreeMem(pData);
  finally
    FreeAndNil(f);
  end;
end.

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

Delphi v kostce

Hrneček Borland

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.

Datum: 2011-02-07 21:15:00 Tagy: optimalizace

soutez