Diskuze: Machr na C# .NET - Nejrychlejší shuffle
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Zobrazeno 50 zpráv z 110.
K personalizaci obsahu a reklam, poskytování funkcí sociálních médií a analýze naší návštěvnosti využíváme soubory cookie. Informace o tom, jak náš web používáte, sdílíme se svými partnery pro sociální média, inzerci a analýzy. Partneři tyto údaje mohou zkombinovat s dalšími informacemi, které jste jim poskytli nebo které získali v důsledku toho, že používáte jejich služby.
Používáme nezbytné cookies pro fungování webu a s tvým souhlasem také analytické a marketingové cookies.
Zajišťují základní funkce, bezpečnost a služby, které sis vyžádal. Nelze je vypnout.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| ITnetwork | ITnetwork | Provoz webu, relace, přihlášení a uložení nastavení cookies. | PHPSESSID, auth_token, sid, itn_consent_impression, __Host-itn_consent | Relace až 1 rok |
| Google Tag Manager | Správa značek a načítání měřicích nástrojů webu. | Žádné | Neukládá se | |
| Google Fonts | Načítání typografie webu. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele | |
| Google Hosted Libraries | Načítání potřebných knihoven a stylů webu. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele | |
| Google reCAPTCHA | Ochrana formulářů a webu před zneužitím. | _GRECAPTCHA, rc::a, rc::b, rc::c, rc::f | Relace až 180 dní | |
| YouTube | Přehrávání vloženého video obsahu. | localStorage, IndexedDB; cookies after playback interaction | Relace až trvalé úložiště | |
| Vimeo | Vimeo | Přehrávání vloženého video obsahu. | __cf_bm, _cfuvid, vuid, localStorage, IndexedDB | Relace až 2 roky |
| Facebook Login | Meta | Přihlášení pomocí účtu třetí strany. | Úložiště řízené poskytovatelem | Relace až 1 rok |
| GoPay | GoPay | Zpracování uživatelem vyžádané platby. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele |
Pomáhají nám porozumět používání webu a zlepšovat ho.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| Google Analytics 4 | Měření návštěvnosti a používání webu. | _ga, _ga_* | Až 2 roky | |
| Microsoft Clarity | Microsoft | Měření návštěvnosti a používání webu. | _clck, _clsk, _cltk | Relace až 1 rok |
Slouží k měření kampaní, personalizaci reklamy a marketingové komunikaci.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| Google Ads | Měření kampaní, reklama a remarketing. | _gcl_au, _gcl_ls | Relace až 90 dní | |
| Meta Pixel | Meta | Měření kampaní, reklama a remarketing. | _fbp, _fbc, localStorage | Až 90 dní |
| Sklik | Seznam.cz | Měření kampaní, reklama a remarketing. | retargeting, sid, szn:* | Relace až trvalé úložiště |
| LinkedIn Insight | Měření kampaní, reklama a remarketing. | bcookie, li_gc, lidc, __cf_bm | Relace až 1 rok | |
| Ecomail | Ecomail.cz | Měření kampaní, reklama a remarketing. | ecmid, Úložiště řízené poskytovatelem | Dle podmínek poskytovatele |
| Atribuce kampaní ITnetwork | ITnetwork | Přiřazení návštěvy a objednávky ke kampani. | campaign_clid[*], user_session_context | Až 1 rok |
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
public void LibcoShuffle<T>(T[] input)
{
Random r = new Random();
for (int i = 0; i < input.Length; i++)
{
int a = r.Next(input.Length);
if (i != a)
{
var b = input[i];
input[i] = input[a];
input[a] = b;
}
}
}
Koukám na to. Jsem na tom podobně. Když ten algoritmus snad napadne
každého. Nebo alespoň já ho tak měl ještě předtím, než jsem ho našel.
Sice jsou asi tři druhy, ale rozdíl v tom moc nevidím. Spíš to bude o tom,
kdo má nejchytřejší Random a jak kdo vyřeší ty operace s čísly. Ještě
jsem zkoušel LINQ, je to několikanásobně rychlejší, ale OutOfMemory
při kopírování zpět z
IEnumerable do pole.
No LINQ určitě rychlejší nebude. Každopádně testovat se to bude na číslech 103 - 104 (říkalo se tady v diskuzi)
Myslíš? Možná máš pravdu. Pouze 103? To bude na tiky procesoru nebo co? To už bude dost nepřesné měření, řekl bych.
Neviem či to takto pôjde na c#, možno ano.
public void LibcoShuffle<T>(T[] input)
{
Random r = new Random();
for (int i = 0; i < input.Length; i += 2)
{
int a = r.Next(input.Length);
i != a ? var b = input[i], input[i] = input[a], input[a] = b : 0;
}
}
Ne, myslel jsem, že máš jinou hlavičku než je v zadání.
Mi to neříkej
celkově mi
tenhle úkol přijde trošku divný, kdyby v tom nebyla ta generika tak by se to
dalo možná nějak uspěchat 
public void SilviniosShuffle<T>(T[] input)
{
// Fisher–Yates shuffle
// Linear congruential generator: r = (a * r + c) % m, m = 2^31, a=1103515245, c=12345
int r = (int) DateTime.Now.Ticks;
for (int i = input.Length - 1; i > 0; i--) {
r = (1103515245 * r + 12345) & 0x7FFFFFFF;
int j = r % (i + 1);
T c = input[j];
input[j] = input[i];
input[i] = c;
}
}
Nevadí, že mám naprosto "blbou" metodu random? Jakože není vůbec
vymakaná, ale náhodná čísla to jsou
A je to zatím nejrychlejší
řešení. Ještě jsem našel něco podobného jako Silvinios, ale to jsem 1.
nevymyslel a 2. to bylo pomalejší.
Jsem si říkal, kde jsi sakra vytáhl ta čísla a on je to standart Céčka
pro rand()
Ale pěkná
práce. U mě zatím nejrychlejší. Schválně, co vymyslí Luboš Běhounek Satik. To
bude zase síla. Už se těším.
Určitě se dá vymyslet něco horšího. Třeba, že některá uspořádání jsou více pravděpodobná, než jiná...
Ja se asi nezucastnim, o vikendu nejsem u PC a do patecni pulnoci musime
dodelat s Lukáš Hruda hru do magickeho leta, Luckin uz pise pribeh... 
Random metodu asi nevytvoříš rychleji a v unsafe kódu toho moc
nevytvoříš s generikou 
Pokud je generika takový problém, tak ji můžeme dát pryč 
No omezil bych to na nějaký daný typ, protože já fakt googloval snad 4
hodiny různé způsoby jak se dá dostat nějak níže a optimalizovat takhle,
ale nic jsem nenašel - a v IL to psát opravdu nebudu 
Příběh už mám
Teď
vymýšlím atributy kouzlům a nepřátelům.
Jenže ona je vážně hrozně blbá
taková odvozená, ale
zároveň náhodná. Generuje to nicméně docela čisté mapy (beztvaré), tak
to snad nebude problém. O unsafe kódu jsem také přemýšlel, ale C# ho
spíše "nedoporučuje" a v některých případech jeho použití i zpomaluje
kód.
Myslím, že pro úkol jako je tento by bylo vhodnější C++ nebo C. Tam by ta generika nebyla takový problém, C++ má šablony, v C se to dá nasimulovat pomocí typedef nebo maker.
Začali jsme brzo, ale měli jsme moc dlouhou pauzu 
Toto je právě příklad, kde to reálně zkusíš
já v C# nikdy s unsafe nepracoval,
tak jsem se "těšil" že si to zkusím a vylepším své znalosti a místo toho
jsem se akorát nasral, že u generiky to nejde 
Já už to zkoušel několikrát. Vždy jsem byl sklamán rozdíly mezi Céčkem a C#. DOvolí toho několikanásobně méně.
Běží to na 1.7GHz i5-3317U. Ale vlákna stejně nepoužívám, rozsekat to na části zabere spoustu času.
Možná to je stupidní otázka, ale kam mám odevzdat tu metodu? Díky
Môj posledný pokus. Podmienka je pole väčšie ako 255 prvkov.
public void LibcoShuffle<T>(T[] input)
{
Random r = new Random((int)DateTime.Now.Ticks);
Byte[] b = new Byte[input.Length];
r.NextBytes(b);
for (int i = 0; i < input.Length; i += 2)
{
var c = input[i];
input[i] = input[b[i]];
input[b[i]] = c;
}
}
Zadání se změnilo na pole intů
(jde to ofc i na to tvoje, ale bude to krapet pomalejší)
public void LibcoShuffle(int[] input)
{
Random r = new Random((int)DateTime.Now.Ticks);
Byte[] b = new Byte[input.Length];
r.NextBytes(b);
for (int i = 0; i < input.Length; i += 2)
{
int c = input[i];
input[i] = input[b[i]];
input[b[i]] = c;
}
}
Zde je můj pokus. Nefunguje pro pole obsahující záporná čísla a není ideální pro míchání malých polí a polí obsahujících pouze jedničky a nuly.
static void Shuffle(int[] arr)
{
Random rnd = new Random();
int size = arr.Length;
int num = rnd.Next() % (size / 2 - 1) + 1;
for (int i = 0; i < size; i++)
{
int pos = (arr[i] + num + i * 2) % size;
int temp = arr[i];
arr[i] = arr[pos];
arr[pos] = temp;
}
}
To minulé nepočítej.
Jsem to předělal na toto:
static void Sidecek123Shuffle(int[] array)
{
Random r = new Random();
for (int i = array.Length - 1; i > 0; i--)
{
int index = r.Next(i);
int tmp = array[index];
array[index] = array[i];
array[i] = tmp;
}
}
To moje nepočítej, našel jsem lepší způsob, ale nějak jsem nebyl doma

Předběžné výsledky jsou následující (viz screenshot) a velmi různé
pro různá pole. Pracuji ještě na testu pro míchaná pole. Také chci zkusit
jestli to opravdu shuffluje. Nevím, jestli to dnes stihnu vyhlásit 
radši se jdi naladit na podzimní atmosféru.
private static void PakoShuffle(int[] input)
{
Random r = new Random();
int n, t;
for (int i = input.Length - 1; i > 0; i--)
{
n = r.Next(5);
t = input[n];
input[n] = input[i];
input[i] = t;
}
}
Můžeš zkusit toto ? byl tam improve skoro 350% oproti tomu předtím.
Kdyby se ti nechtělo, hodil bys mi zdroják a já bych si to pustil u sebe ?

Proměřil jsem i náhodná pole. Vypadá to na bitvu mezi Brisingrem a Davidomilem. Snad jsem tam někde neudělal chybu, jsem docela unavený. Zdroják prozatimního testu je zde: http://www.itnetwork.cz/dev-lighter/208
Jdu se kouknout jak vám to kluci prohazuje.
Podle výsledků bych to jednoznačně viděl na to, že vede Michael Olšavský
Vypadá to tedy, že z testu vyšel nejlépe Lukáš Hruda, získává tedy
Machra na C#
Druhý je
Silvinios. Metody Brisingra a Davidomila mi nějak nedělaly to, co měly. Pro
případ přikládám celý zdroják testů: http://www.itnetwork.cz/dev-lighter/209 .
Luckinovu adresu prosím x do PM.
Sakra. To je dost trapný
a to sem tomu algoritmu tak veril... Stacilo pritom pridat jednu
nahodnou navic... A ten cas by se skoro nezvedl. A vubec. mel jsem to nechat na
svem prvnim pokusu. Vypada to, ze by to s tim casem nebylo tak spatne, kdyz to
davidomilovi take nefunguje. Mam na tyhle machry teda stesti...
doufam, ze priste to vyjde.
Omlouvam se, za klamavy aloritmus. Nahodnost pentia nebyla schvalne.
Tomu už ani nevěřím... :/
Chce to víc kontrolovat. Přitom sem to opravil za pár
minut........................

Zobrazeno 50 zpráv z 110.
