Tippek, trükkök bejegyzései

Apró, de hasznos informatikai trükkök

Ha rövid a tápkábeled...

 

Csendmániám következő áldozata a tápom volt. Lecseréltem egy 300 wattos passzív FSP Zen tápra. Gondolom néhányan felsikoltanak most, hogy CSAK 300 WATT? Mire elég az? Bátran mondhatom hogy majdnem bármire. Hacsak nincs egy 2videokártyás 4magos erőműved, akkor bőven elég. Lásd EZT a táblázatot.

300 watt gyakorlatilag bőven elég egy modern (nem extrém számítógépnek). De nem is erről akarok írni, hanem arról, hogy jártam. Ugyanis ennek a tápnak kicsit rövidebbek a kábelei az átlagnál, a házam felépítése miatt pedig további centiket veszítettem a hosszukból. Az lett a vége, hogy az alaprapra menő 12voltos "P4" csatlakozó egyszerűen nem ért el az alaplapig. 

Mit lehet tenni? Első felindulásból elkezdtem keresgélni a neten, de egyszerűen nem létezik ilyen hosszabbító. Maradt a hómbarkács megoldás: levágni, betoldani másik kábelt, visszaforrasztani. Nem ez lett volna az első eset, hogy forrasztópákát kellett volna használnom, de elgondolkoztam, hogy jó-e nekem az, ha egy 10 amperes kábelt összegányolok. Arra jutottam, hogy amíg nem muszáj, inkább nem rondítok bele.

Elmentem pár számtechboltba a környéken, hátha tudnak valami okosságot mondani. Az első boltban szimplán hülyének néztek. Megkérdezték minek kell ez nekem? Mondom mert rövid a tápkábel. -Az nem lehet. Mondom de rövid, tudnak-e valami tippet adni mit csináljak. -Nem. Nincs valami olyan kábelük esetleg amiből össze lehet barkácsolni a hossszabítót? -Nincs. El fog szállni az alaplapod, ha ilyeneket csinálsz. Közbe úgy nézett rám a faszi mintha szetségtörést követnék el. Gyorsan ott is hagytam a boltot.

A következő boltban már rendesebbek voltak. Kábelt ugyan nem tudtak ők sem adni, de azt mondták vágjam le nyugodtan és toldjak bele, ha jól csinálom nem lesz semmi baja.

A harmadik boltban volt a legjobb tapasztalatom. Először is megértették a problémámat. Aztán ők is elkezdtek gondolkodni a megoldáson, nem csak ki akartak dobni. Végül arra jutottunk, hogyha veszek egy 24ből 20 tűs tápkábel átalakítót, akkor azon biztos lesz olyan rész ahova be tudom dugni a P4 kábelt, a többi részét meg egyszerűen levágom és kész.

 

Meg is vettem és itthon elkezdtem próbálgatni, hova fér bele a 12voltos csatlakozó. Két helyen is belement, valahol az elején meg a közepénél.

Aki ismeri ezt a csatlakozót,  tudja, hogy van rajta egy műanyag biztonsági kampó ami megakadályozza, hogy miután bedugtuk, önszántából szét tudjon csúszni a csatlakozás. Én ezt a funkcionalitást nem szerettem volna elveszteni, főleg hogy jó eséllyel feszülni fog a kábel. Hiszitek vagy sem, a 24-20 átalakító másik végén, pont ott ahova a P4 kábel belement, egy ugyanilyen műanyag kampó van. Pontosan ugyanolyan mint az eredeti tápcsatlakozón. Ez vagy véletlen, vagy csak szerencsém volt, minden esetre nagyon örültem neki. 

Gyakorlatilag a 24-20as tápátalakítóban integrálva van egy 12V-os kábel hosszabbító is, csak meg kell szabadulni a feleslegtől :) Levágtam tehát a két szélét, és lett egy tökéletes "gyári" hosszabbítóm. Beszereltem, épp elég hosszú volt, és azóta tökéletesen megy vele a gépem.

 

12V 20



 

 


Üres Recent Projects lista VS2005 -ben

Egy jó ideje fennt van a gépemen a Visual Studio 2005, párszor már újra is telepítettem, de ez a bosszantó hibája sosem szünt meg: a Recent Projects lista mindig üres volt. Akármit csináltam vele, nem volt hajlandó megjeleníteni az előzőleg használt projecteket.

De most büszkén jelenthetem be: rájöttem a megoldásra! Vagyis már 1 éve közzétették, csak most találtam rá :)

Az a lényeg, hogy valamiért a VS2005 a Windows MRU beállításai használja, és ha a windówsban le van tiltva a legutóbb használt dokumentumok gyűjtése, akkor nagy ívben lesz*rja, hogy a saját menüjében mik vannak beállítva. 

Gyors megldás a problémára, ha az alábbi registry kulcsban:
"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer"
Módosítjuk alábbi DWORD értékét:
"NoRecentDocsHistory"
0-ra.

 

Forrás: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=108731

 

 

 



Windows Server 2008 telepítés Solaris mellé

Szert tettem egy kis szabadidőre, meg egy éppen használaton kívüli Sun Ultra 20 wörksztésönre, és úgy gondoltam jó lenne kipróbálni a jövő windows szerverét. Töltöttem egy Windows Server 2008 Release Candidate -t és elkezdtem telepíteni...

Tudni kell, hogy a Sun gépen alapból Solaris van, amit nem állt szándékomban bántani. Volt rajta két partíció: az elsőn maga a Solaris, a másodikra szerettem volna feltenni a szervert. Természetesen a Solaris particóról indult a gép, mivel eddig nem volt rajta másik OS.

Bootolok a telepítőDVDről, és meglepő módon egy full dizájnos Vista-sztájl felület fogad. Ezidáig a WinXP volt a legmodernebb rendszer amit telepítettem, úgyhogy igencsak meglepődtem a kékhátteres karakteres felület, és a kötelező F3 nyomás hiányán. De hát na, haladni kell a korral. Ja, az egér is működik, tök jó. Írjam be az aktivációs kulcsot vagy mit. Ezzel nem volt gond, mivel az MStől ingyen lehet kérni egy 2008 áprilisáig érvényes próbalicenszt. Aztán 2 opció tűnik fel: Upgrade, vagy Custom advanced mód. Az Upgrade nem is választható, mondjuk sejtem miért :)

Kiválasztom a Custom módot, megjelennek a partíciók. Kiválasztom a másodikat, Delete. Aztán New, és újra létrehozom, biztos ami biztos. Format-tal megformázom. Sikerült. Örülök. Na és akkor Next. Mondon NEXT. Nem akarja... Aszondja "Windows is unable to find a system volume that meets its criteria for installation". Hát de vaze, most csináltam neki frissen egy új particiót a saját particionálójával!

Újraindítottam, hátha megjavul. Sajna most nem jött be. Tököltem vele, próbálgattam mindenféle módon órákig. Semmi használható hibaüzenetet nem tudtam belőle kicsalni. Nem talál magának particiót, kész. Aztán egy hirtelen ötlettől vezérelve (kösz lortech!) fogtam egy bootmagicet és átállitottam az üres ntfs particiót bootable-ra a Solarisos partíció helyett.

Csodák csodája, feltelepült.

Kész. Ekkor vertem az asztalt egy darabig (csak mert a Sunos billentyűzetet nem illik bántani). Lehet, hogy én vagyok béna. Elismerem, fel sem merült bennem hogy ez lehet a kínja. De legalább kiírná, hogy ezért nem hajlandó települni! Az XP telepítője sosem akadt fenn ilyenen, legfeljebb nem az XP indult el, hanem az előző oprendszer. De feltelepült szó nélkül, aztán újraindításkor úgyis rájövök hogy át kéne állítani az aktív particiót...

 

Hát ez van. Jegyezzétek meg: a Win2008 csak az aktív particióra hajlandó felmenni! (de a telepítőjében nincs mód kiválasztani az aktív partíciót.)

 


Pénzes trükk

Hogyan dugjunk át egy érmét egy nála kisebb lyukon?

Anélkül hogy elszakítanánk a papírt amin a luk van :)

 


Coin Through A Smaller Hole - The best video clips are right here

 

 

Ha tetszett, ITT egy másik trükk, nézd meg!

 


Internetes Bankkártyák

Az interneten barangolva előbb-utóbb szembe találjuk magunkat a problémával: Szeretnénk vásárolni. Igen ám, de mivel?

A legáltalánosabban elterjedt internetes fizetőeszköz a bankkártya vagy hitelkártya (credit card). Ezek közül is a két legnépszerűbb típus a MasterCard és a Visa. Azonban ezeknek csak a dombornyomott változatait használhatjuk online (vagyis igazából offline, de ez egy másik téma). Ilyen dombornyomott kártyákat bármelyik bankban igényelhetünk. Bár tudnunk kell, hogy ez nem olcsó mulatság. Különböző feltételeknek kell megfelelnünk, hogy ilyen kártyákhoz jussunk. Például minimum 50 ezer forint fedezet a számlánkon, rendszeres havi jutattás, stb. Továbbá ezeknek a kártyáknak az éves díja is többszöröse az alább bemutatott alternatíváknak. Ennek ellenére igen népszerűek ezek a kártyák, számos előnyük van az Electron kártyákhoz képest, főleg külföldön. De csak azért, hogy interneten vásároljunk, nem éri meg ezeket választani. Akkor mi a megoldás?

Első lépésben megpróbálkozhatunk Visa Electron kártyánk használatával. Egyre több bank engedélyezi az ilyen tipusú kártyák internetes használatát, de ez koránt sem jelenti azt, hogy akárhol használhatók. Jelenleg leginkább szerencse kérdése hogy az adott helyen elfogadják-e Electron kártyánkat vagy nem.

A legjobb megoldás az internetes fizetésre a virtuális bankkártyák használata. Ezek csak a legszükségesebb adatokat tartalmazzák: kártyaszám, lejárati idő, CVC2 kód. Nincs rajtuk mágnescsík, és nem is kell aláírni őket, nem használhatók automatákban. Csak arra jók, hogy az interneten fizethessünk velük. Lehetnek műanyagból, papírból, sőt akár SMSben is érkezhetnek.

További előnyük a hagyományos bankkártyákhoz képest a biztonság. A legtöbb banknál külön kártyaszámla tartozik ezekhez a kártyákhoz, melyre közvetlenül a fizetés előtt vezetjük át a szükséges összeget az internetbankban. Így, ha meg is próbálnának átverni, és több pénzt levonni akkor nem járnak sikerrel. Ugyan ez a módszer véd a szám ellopása ellen is: ha valahogy megszerzik a kártyaadatainkat, akkor sem tudnak vele mit kezdeni, mert a hozzá kapcsolódó számlán alapesetben nincsen pénz.


See The Invisible Data On Magnetic Cards! - Watch the best video clips here

Nézzünk pár konkrét megoldást!

CIB Bank

  • Neve: Internetkártya
  • Ára: ingyenes (CIBEZZ számlával), egyébként 800Ft/év
  • Típusa: MasterCard
  • Védelem: különálló alszámla

Nekem ilyenem van, eddig majdnem mindenhol elfogadták. Külföldi szerencsejáték-oldalakon lehet gond vele. 26 éves kor alatt teljesen ingyenes. Csak ajánlani tudom.

Erste Bank

A limit egy bizonyos idő elteltével visszaáll az alapéertékre (1ft), így elég biztonságos. Nagy hátránya viszont, hogy a limitek csak a telefonos banki szolgáltatással módosíthatók, az internetbankban nem. A telebank pedig kék számmal hívható aminek ugye díja van. Ha az ember sűrűn fizet az interneten, akkor szerintem macerás a használata, egyébként nem rossz. Csak ne lenne több mint havi 100 Ft a számlavezetési díj.

OTP Bank

Nem sokat tudok róla mondani, nem volt még vele tapasztalatom. Drága.

Inter-Európa Bank

  • Neve: Egyszer használható kártyaszám SMSben, a KártyaŐr szolgáltatás keretében
  • Ára: a Kártya őr szolgáltatás havidíja 300 Ft, diákoknak 150Ft
    Továbbá a kód igénylése 30 Ft/darab SMSben, és 75Ft/db WebBankon keresztül igényelve.
  • Típusa: MasterCard
  • Védelem: Csak egyszer használható, utána érvénytelenné válik.

Az egyszer használatos kódok nyújtják a legnagyobb biztonságot az interneten. Amint a tranzakció lezajlik, semmire nem használható a kártyaszám. Ha még nem vagy 18, nyithatsz Teenager számlát, amihez szintén megrendelhető a KártyaŐr. A számlavazetés díja 150Ft/hó.

 

A lista koránt sem teljes körű, írjatok a kommentbe ha tudtok még valami jót! Amúgy ITT van az összes internetes bankkártya listája, csak hogy legyen mit böngészned :)

Remélem sikerült hasznos segítséget adnom a választáshoz. Felhívom a figyelmeteket, hogy a kártya költségeihez még hozzáadódnak a számlavezetés költségei, amik bankonként nagyon eltérőek. A legtöbb banknak van kedvezményes számlacsomagja a diákok számára. Érdemes ezeket választani (már ha diák vagy:). Például a CIBEZZ számla internetkártyástul, webbankostul tök ingyen van.

További hasznos információkat az internetes fizetésről ITT találhatsz.

+++ Ma megtapasztaltam hogy a CIBes kártya sem jó mindenre. Elvileg a MasterCardnak van valami szerencsejáték-ellenes szabályozása. Egy ilyen szájtra akartam vele befizetni, és bár ott van a MasterCard logo a használható kártyák között, azt írták, hogy az én kártyámat egy US bank bocsájtotta ki, és azoknak nem szabad játszani. Szereznem kell egy virtuális VISA-t is... :)

 


Bazi erős vinyómágnes

Berheld szét te is a régi winyódat, bazierős mágnes van benne! Állítólag lassítja a villanyórát, de én nem vettem észre :)

 


Strong Magnets From Your HDD - A funny movie is a click away

 


Linux hack

Mit tegyünk, ha elefelejtettük a root jelszavunkat?



Linux Hacking - video powered by Metacafe

Lebegő gyertya

Nem igazán informatikai téma, de néha lazíthatunk is, nem igaz? :)


How To Make Floating Candle - video powered by Metacafe

Sebességre optimalizálás dinamikus kódgenerálással

"Hogyan írjunk olyan programot, mely olyan programot ír,
ami százszor gyorsabb, mint ha mi írtuk volna."

Bevezető

A következőkben bemutatom, hogyan lehet a .NETes programokban bizonyos esetekben akár 100szoros (nem elírás, százszoros) sebességnövekedést elérni. A módszer lényege, hogy egy specifikus feladat végrehajtásához a programunk futás közben generálja le a legoptimálisabb IL assembly kódot. Ehhez a System.Reflection.Emit namespace metódusait használjuk.

A dinamikus kódgenerálás alkalmazása

A reflection emit (általában így nevezik) technológia alkalmazható többek közt:

  • Scriptek végrehajtására a webböngészőben
    1. A böngésző betölti a HTML oldalt
    2. A böngésző kiolvassa a scriptet az oldalból és átadja a scriptértelmezőnek (script engine)
    3. A szkriptértelmező létrehoz egy dinamikus programot a memóriában
    4. A szkriptértelmező a reflection emit segítségével legenerálja a scriptnek megfelelő assembly kódot a dinamikus programba.

  • Reguláris kifejezések lefordítására (compile)
    1. A fordító talál egy új regexet a programban.
    2. A regexet a programozó lefordítandónak jelölte, ezért a fordító készít hozzá egy specifikus kereső osztályt.
    3. A fordító értelmezi a reguláris kifejezést készít egy, csak a megadott kifejezést végrehajtó MSIL kódot, melyet reflection emittel beletesz az osztályba.
    4. A fordító példányosítja az előbb elkészített osztályt és lefuttatja a benne lévő kódot. Így hajtja végre a regexet.
    5. Ha a fordító legközelebb ugyanezzel a regexxel találkozik a forráskódban, fogja a hozzá elkészített osztályt, példányosítja és végrehajtja. Ezzel nagyban gyorsítja a program futását.

  • Algoritmusok specializációjára, egyedi esetre való optimalizációjára Pl:
    • Kód készítése megadott XSL séma validálásához
    • Célprogram készítése megadott XSLT transzformáció végrehajtásához
    • Egy általános titkosító algoritmus optimalizálása konkrét kulcsra

  • Saját kód generálására futásidőben
    • Például scriptelhető programok létrehozásához

A példaprogram

A reflection emit bemutatásához egy egyszerű példát választottam az O’reilly: Programming C# című könyv 18. fejezetéből:

Írjunk programot, amely összeadja 1-től n-ig az egész számokat!
Jelen esetben az n legyen 20.

Mi sem egyszerűbb, gondolnánk, egy for ciklus az egész:

  // sum numbers with a loop
 
public int DoSum (int n)
  {
       int result = 0;
       for(int i = 1;i <=n;i++)
       {
            result += i;
       }
       return result;

  }

Igen ám, de gondoljunk csak bele, hogyan működik a for ciklus! Van egy ciklusváltozó, mely minden lefutáskor növekszik, és van egy feltétel, mely szintén minden iterációban kiértékelődik. Ez a feladatunk szempontjából teljesen felesleges művelet, csak a vezérlési szerkezet működéséhez szükséges.

Mennyivel gyorsabb lenne egy olyan program, mely tényleg csak azt teszi, amire szükségünk van? Jelen esetben visszaadja az 1+2+3+4+5+…+n értéket.

  // brute force by hand
 
public int DoSum2()
  {
      return 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11
      + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20;
  }

Ebben az esetben az algoritmusunk tényleg a lehető legoptimálisabb, semmi felesleges funkciót nem végez.

Sebességmérés

Tehát mennyivel is gyorsabb így a számítás?

Ennek kiderítéséhez készítsünk egy teszt osztályt, mely egymilliószor kiszámolja az első 20 szám összegét az első, majd a második módszerrel:

Forráskód letöltése

Az eredmény:

Loop: Sum of (20) = 210
The elapsed time in milliseconds is: 156,25
Brute Force: Sum of (20) = 210
The elapsed time in milliseconds is: 31,25

Mint látjuk, az „optimális” megoldás 5-ször gyorsabb volt a for ciklusnál.
Valójában ez az eredmény több okból sem felel meg a valóságnak.

Az egyik ok a Windows működésében keresendő: A Windows Timer felbontása alapbeállításban 7,8125 ms. Ez azt jelenti hogy minden timerrel mért érték 7,8125 msnek a többszöröse. Ennél fogva ilyen rövid időtartamokat egyszerűen nem tudunk pontosan mérni. Két féle megoldás létezik a problémára:

  1. A Boot.ini ben az OSt betöltő rekordhoz hozzáteszünk egy /TIMERES=10000 kapcsolót. Ezzel a timer felbontását 0,9766 msre állítjuk. Én igazából ezt nem próbáltam ki, mert nem tudom milyen hatással van a rendszer működésére. A mi esetünkben úgysincs szükség ilyen fokú pontosságra, elég ha az arányokat látjuk. Ha valaki kipróbálja, írjon egy kommentet a tapasztalataival :)
  2. Sokkal többször futtatjuk le a tesztet, így a pontatlanságból eredő hiba kisebb lesz.

 

A másik ok pedig az, hogy csaltam. Vagyis igazából a fordító csal, mikor lefordítja a forráskódot. A kész programot Reflectorral vagy ILDasmmal megvizsgálva észrevehetjük a turpisságot:

 

 .method public hidebysig instance int32 DoSum2() cil managed
  {
        .maxstack 1
        .locals init (
                  int32 num1)
        L_0000: nop
        L_0001: ldc.i4 210
        L_0006: stloc.0
        L_0007: br.s L_0009
        L_0009: ldloc.0
        L_000a: ret
 
}

A fordító kiértékeli az összeadást és programba csak a végeredményt írja bele.
Ezt kiküszöbölhetjük, ha a függvényt az alábbi módon írjuk meg:

 

  public int DoSum3()
  {
      int ret = 0;
      ret += 1; ret += 2; ret += 3; ret += 4; ret += 5;
      ret += 6; ret += 7; ret += 8; ret += 9; ret += 10;
      ret += 11; ret += 12; ret += 13; ret += 14; ret += 15;
      ret += 16; ret += 17; ret += 18; ret += 19; ret += 20;
      return ret;
  }
 

Javított sebességmérés

Összefoglalva tehát az eddigi ténykedéseinket futtassuk le a módosított tesztet 10milliószor, mind a 3 függvényünkre.

Forráskód letöltése

Eredmény:

Loop: Sum of (20) = 210
The elapsed time in milliseconds is: 1765,625
Brute Force: Sum of (20) = 210
The elapsed time in milliseconds is: 250
Real Brute Force: Sum of (20) = 210
The elapsed time in milliseconds is: 406,25

Így is még valamivel több, mint 4szer gyorsabb az „optimális” algoritmusunk.

Dinamikus metódusok

OK. Ezután a rövid kis bevezető után vizsgáljuk meg újra a feladatot!

Így 20nál még nem gond leírni a forrást, de mit csináljunk ha 2000ig szeretnénk összeadni a számokat? Na mit? Használjunk reflection emitet! Vagyis generáljuk le futásidőben, a paraméter függvényében az optimális kódot. De hogyan is tegyük ezt?

Dinamikus metódust generálni a .NET 2.0 előtt csak úgy lehetett, hogy készített az ember egy dinamikus assemblyt, abba egy modult, abba osztályt, és végül abba a metódust. Majd az egészet példányosítani kellett, végül meg lehetett hívni a metódust. Szóval elég macerás volt.

Szerencsére nekünk már jobb a helyzetünk, mivel a 2-es .NETben bevezették a DynamicMethod osztályt. Segítségével a fenti házépítő procedúra nélkül, egyből gyárthatunk dinamikus metódust.

Alapvetően kétféle dinamikus metódus létezik: az egyszerű és az objektumhoz csatolt. Az egyszerű dinamikus metódus úgy viselkedik, mintha modulszintű statikus metódus lenne. Az objektumhoz csatolt metódusnál pedig egy példányosított objektumhoz kapcsoljuk hozzá a generált metódust.

Dinamikus metódusok készítése

A példánkhoz egy egyszerű dinamikus metódust fogunk készíteni. A procedúra 5 lépésből áll:

  1. Deklarálunk egy delegate típust. Ennek segítségével fogjuk majd meghívni a dinamikus metódust.

    private delegate int SumItInvoker();

  2. Készítünk egy tömböt, mely a metódus paramétereinek típusát tartalmazza

    Type[] methodArgs = new Type[0];

  3. Készítünk egy DynamicMethod objektumot. Ez fogja azonosítani a készülő dinamikus metódusunkat. A konstruktor paraméteriben meg kell adni
    • a függvény nevét
    • a visszatérési érték típusát
    • a paraméterek típusait tartalmazó tömböt
    • egy modult vagy objektumot, amelyhez hozzárendelődik a metódus

DynamicMethod sumIt = new DynamicMethod(
       "SumIt",
       typeof(int),
       methodArgs,
       typeof(DynamicSum).Module);

    A név megadása igazából csak a debuggolást könnyíti meg, ezzel a névvel a későbbiekben úgysem lehet hivatkozni a metódusra.

  1. Legeneráljuk a dinamikus metódus törzsét. Elkérjük a DynamicMethodunk ILGeneratorát, majd ennek segítségével emittáljuk az optimalizált összeadófüggvényünket:

                  ILGenerator generator =
             sumIt.GetILGenerator();
           // Ezt a kódot a DoSum3 függvény ILkódja alapján
           // lehet elkészíteni.
           // A stackbe 0át tesz. A megadott érték eléréséig
           // i-t a stackbe teszi konstansként.
           // Összeadja a stack tetején lévő két értéket
           // Az összeg a stackben lesz.
           generator.Emit(OpCodes.Ldc_I4, 0);
           for (int i = 1; i <= theValue;i++)
           {
                generator.Emit(OpCodes.Ldc_I4, i);
                generator.Emit(OpCodes.Add);
           }
           // return the value
           generator.Emit(OpCodes.Ret);

  2. Készítünk egy példányt az 1es pontban deklarált delegateből és hozzárendeljük az elkészített dinamikus metódushoz annak CreateDelegate függvényének segítségével.

    SumItInvoker DoSum = null;
    DoSum = (SumItInvoker) sumIt.CreateDelegate(typeof(SumItInvoker));

    Ezt a lépést a példaprogram konstruktorában fogjuk végrehajtani.

Sebességmérés újra

Módosítsuk a teszt osztályt, hogy az újonnan készített dinamikus függvényünket is vizsgálja.
A számokat 2000ig adja össze, egymilliószor.
A teljes forráskód innen tölthető le. (Ez tartalmazza a dinamikus assemblyvel készített metódust is, ennek magyarázatára nem térek ki.)

Az eredmény:

Sum of (2000) = 2001000
Looping. Elapsed milliseconds: 10328,125 for 1000000 iterations
Sum of (2000) = 2001000
Dynamic Assembly. Elapsed milliseconds: 171,875 for 1000000 iterations
Sum of (2000) = 2001000
Dynamic Method. Elapsed milliseconds: 125 for 1000000 iterations

82szeres gyorsulás! Azt hiszem, az eredmény magáért beszél.

Összefoglalás

Láthattuk, hogy egy egyszerű összeadás esetében is az optimális, futásidőben generált kód akár 80szor gyorsabban fut, mint egy hagyományos ciklus. Nem állítom, hogy minden esetben kifizetődő a dinamikus metódusok használata. Vannak esetek, mikor a metódus generálási idejével együtt lassabban fog lefutni a dinamikus kód, mint a hagyományos.

De ha valaki olyan alkalmazást fejleszt, ahol fontos a sebesség, próbálja ki, mennyivel gyorsabb a dinamikus metódusok használata. Igen, kell hozzá ismerni az MSIL assemblyt, de nem muszáj 0ról megírnunk az assembly kódot. C#ban leírhatjuk az optimális megoldás részleteit, majd Reflectorral, vagy ILDasmmal megvizsgálhatjuk a kódot, így össze lehet építeni bonyolultabb algoritmusokat is assemblyben. Nem egyszerű, de megéri a fáradtságot.

Remélem tetszett a cikk, és ha nem is fogod használni a dinamikus metódusokat a közeljövőben, legalább tudod, hogy léteznek, és milyen hatékonyak :)

 

Felhasznált irodalom:
A cikkhez felhasznált forráskódok az O'Reilly: Programming C# 4th edition című könyv példaprogramjain alapulnak. (Chapter 18\LoopVsBruteforce és Chapter 18\ReflectionEmit)
További infók és példaprogramok találhatók a reflection emitről az MSDN oldalain.


Reflector, avagy világíts bele a fekete dobozba!

Gondolkoztál már azon, hogy hogy működhet például az ArrayList? Szerettél volna belekukkantani egy StreamReader életébe? Szeretnéd úgy optmalizálni a programodat, hogy tudod, mi folyik a háttérben?

Akkor itt a megoldás! Világíts bele a fekete dobozba! Használj .NET Reflectort!

A felhasználók véleményeiből:

  • "- Iszonyú hasznos kis util, amióta kipróbáltam, mindig ezt használom!"
  • "- Egyszerűen nem tudok szabadulni tőle! Ez használni kell!"
  • "- Egy szó: NÉLKÜLÖZHETETLEN"

Ha valaha is foglalkoztál .NETes fejlesztéssel, mindenképpen próbáld ki. Ingyenes és nagyszerű!

Ja, és hogy mire jó?
Végülis is csak egy class browser, explorer, analyzer és dokumentáció nézegető, amivel minden .NET assemblyt megnézhetsz, kereshetsz bennük, visszafejtheted és elemezheted őket C#, Visual Basic vagy IL nyelven. Szóval semmi különös :)

De ez még nem minden!
Számtalan hasznosabbnál hasznosabb kiegészítő tölthető le hozzá INNEN!
Többek között egy olyan is, amely integrálja a programot a VisualStudioba így ni:

Reflector Demo


Van még hozzá

  • Delphi és Managed C++ nyelvű megjelenítő
  • Közvetlenül fájlba exportáló, bármilyen Reflector által támogatott nyelven.
  • Eltérés kereső (diff) két assembly között
  • Vizuális típus megjelenítő
  • Form megjelítő
  • Hívási lánc megjelenítő gráfos formában
  • Kódgenerátor COM komponens használatához

és további sok-sok kiegészítő, melyek kipróbálása után már el sem tudjuk képzelni az életünket nélkülük :)


A Reflection és a Valóság vagy valami ilyesmi :)

Találtam egy tök jó kis összefoglalót a Reflectionos trükkökről, íme:

http://weblogs.asp.net/avnerk/archive/2006/12/12/crossing-the-line-reflection-and-reality.aspx


Feltételesen lefutó hibakereső függvények készítése

Programozás közben igen hamar belefutunk abba a problémába, hogy itt-ott jó lenne kiíratni egy változó értékét, hogy ellenőrizzük, hogyan fut az algoritmusunk. Gond egy szál se, írassuk ki! Igen ám, de miután végeztünk a fejlesztéssel, jó lenne ezeket a kiíratásokat valahogy eltüntetni a végleges verzióból. Mihez is kezdjünk?


1. megoldás:

Kommentezzük jól körül a feltételes részeket, majd a végleges verzióban magát a programrészletet is kommentezzük ki!

class Program
      {
            static void DebugWrite(object debugdata)
            {
                  Console.WriteLine("Debug vagyok, üssetek! A változó értéke: {0}\n", debugdata);
            }

            static void Main(string[] args)
            {
                Console.WriteLine("Elindultam. Számolok.");               
                  //bonyolult számolóalgoritmus
                  int i;
                  for ( i = 0; i < 10; i++ )
                  {  
                        /*DEBUG BEGIN*/
                        DebugWrite(i);
                        /*DEBUG END*/
                  }              
              Console.WriteLine("Végeztem. Az eredmény: "+i);
                  Console.ReadLine();
            }
      }


Előnyök: rövid, házifeladat szintű programoknál egyszerűen használható, nem igényel különösebb tudást.

Hátrányok: minél többször alkalmazzuk annál biztosabb, hogy a végén bennemarad egy pár felesleges kiíratás.


2. megoldás:

Használjuk az #if, #else, #endif előfeldolgozó direktívákat!

class Program
      {
 
#if DEBUG
            static void DebugWrite(object debugdata)
            {
                  Console.WriteLine("Debug vagyok, üssetek! A változó értéke: {0}\n", debugdata);
            }
#endif 
            static void Main(string[] args)
            {
                Console.WriteLine("Elindultam. Számolok.");               
                  //bonyolult számolóalgoritmus
                  int i;
                  for ( i = 0; i < 10; i++ )
                  {  
#if DEBUG
                        DebugWrite(i);
#endif                       
                  }              
              Console.WriteLine("Végeztem. Az eredmény: "+i);
                  Console.ReadLine();
            }
      }


Előnyök: Majdnem minden programozási nyelv támogatja ezeket. Pontosan szabályozni tudjuk mely programrészek kerüljenek bele a végleges verzióba.

Hátrányok: széttagolják és nehezen áttekinthetővé teszik a forráskódot. Minden egyes debugfüggvény-híváskor alkalmazni kell őket.

3. megoldás:

Használjunk Conditional attribútumot!

class Program
      {
            [Conditional("DEBUG")]
            static void DebugWrite(object debugdata)
            {
                  Console.WriteLine("Debug vagyok, üssetek! A változó értéke: {0}\n", debugdata);
            }

            static void Main(string[] args)
            {
                Console.WriteLine("Elindultam. Számolok.");               
                  //bonyolult számolóalgoritmus
                  int i;
                  for ( i = 0; i < 10; i++ )
                  {  
                        DebugWrite(i);
                  }              
               Console.WriteLine("Végeztem. Az eredmény: "+i);
                  Console.ReadLine();
            }
      }



Előnyök: Szép :) Csak a függvény definíciójakor kell alkalmazni, a függvényhívásoknál nem.
Hátrányok: A feltételes függvény mindenképpen belefordul a programba, csak sosem hívódik meg.

 

Mint látjuk a legszebb és legáttekinthetőbb megoldást a Conditional attribútum használata nyújtja, mely a System.Debug namespaceben van. Egyszerre több feltételt is vizsgálhatunk a következő formában: 

[Conditional("DEBUG"), Conditional("TRACE")]

Ekkor a feltételek vagy kapcsolatban állnak egymással, tehát elég az egyiknek teljesülnie.
Fontos tudni azonban az alkalmazásának a feltételeit:

  • A feltételes függvénynek nem lehet visszatérési értéke. Csak void lehet.
  • Classon és structon belül deklarálható, interfaceben nem.
  • Nem kaphat override módosítót. Ha egy virtual függvényt Conditional attribútummal látunk el, akkor annak minden override párja automatikusan Conditional lesz.
  • Interface-metódus implementációjakor nem használható.

Jelentős különbség Conditional, és az előfeldolgozó direktívák között, hogy míg az attribútum egy teljes függvényre vonatkozik, a direktívákkal utasítás szinten szabályozhatjuk a végrehajtást. A Conditional attribútummal ellátott függvények belefordulnak a végleges programba, de futtatáskor a memóriába már nem töltődnek be. A direktívákkal szabályzott programrészek nem fordulnak le, ha a megadott feltétel nem teljesül.

Természetesen a .NETben sok más kifinomult technika létezik még a hibakeresés elősegítésére. A fenti egyszerű példák csak a feltételes függvényhívások demonstrálására készültek.

Referencia:


"Rejtett" zene a Windowsban

Mindannyian tudjuk, hogy a Windows tele van meglepetésekkel. Nem ma kezdtem ezzel az OS-el foglalkozni, de még engem is érnek meglepetések :)

Tudtátok például hogy a Windows XP standard telepítésekor fent hagy a winyón egy tök jó zenét? Elvileg ezt a telepítés utáni konfigurálóprogram - "Out of Box Experience" (?) - alatt játssza, bár én még sosem hallottam.

Ha meg akarjátok hallgatni, a Futtatásba (Win+R) írjátok be:

%WINDIR%\System32\oobe\images\title.wma

Automatikus verziószám növelés Visual Studio 2005ben

A külföldi weblapokon sokan azt hiszik, hogy Visual studio 2005 nem képes automatikusan növelni a build numbert minden fordításkor. Mindenféle makrókat írnak rá, meg összevissza gányolnak.

Te is azt hitted?

Akkor ki kell, hogy ábrándítsalak. A Visual Studio 2005 egyszerű módon rávehető arra, hogy a programod minden fordításakor autoincrementelje a buildnumbert.

De mi is az a buildnumber és mire jó az, ha automatikusan növekszik?

Minden .net assemblynek van egy 4 tagú verziószáma, mely 4 darab szám . -tal elválasztva. Például: 1.1.2165.1574. Ennek felépítése a következő:

  • Főverzió
  • Alverzó
  • Build szám
  • Javítás

Pl: Mikor .NET -es dll-t használsz, akkor annak a verziószáma alapján dönti el a keretrendszer, hogy melyiket töltse be a sok ugyanolyan nevű dll közül.

Ha minden fordításkor automatikusan növekszik az utolsó 2 tag, akkor bármikor megtudhatod egy lefordított binárisról, hogy körülbelül mikor készítetted, és mennyire van lemaradva az aktuális forráskódtól. Meg még ki tudja mire jó :)

OK, hogyan vegyem rá a VSt hogy növelgesse nekem a buildet?

Egyszerűen:

  1. A Solution Explorerben a Properties mappából nyisd meg az AssemblyInfo.cs fájlt!
  2. Scrollozz az aljára, ott kell lennie egy olyan bejegyzésnek, hogy

    [assembly: AssemblyVersion("1.0.0.0")]

  3. Ezd írd át a következőre:

    [assembly: AssemblyVersion("1.0.*")]

  4. Mentsd el solutiont. Ezzel készen is vagy.

Ez tényleg egyszerű! És hogyan lehet kiíratni a verziószámot a futó programban?

A Reflection osztályt kell hozzá használni. Ennek segítségével a program futás közben tud információkat lekérdezni saját magáról.

Például, tegyük fel hogy a Form-od címsorában szeretnéd látni a verzószámot. Ehhez a Készíts egy Load eseményt, és az eseménykezelő pedig az alábbi legyen:

private void Form1_Load(object sender, EventArgs e)
{
     System.Reflection.AssemblyName a = System.Reflection.Assembly.GetExecutingAssembly().GetName();
     this.Text += " " + a.Version.ToString(4);
}

Továbbá külön-külön is elérheted a verziószám tagjait a megfelelő propertyk használatával.


Registry-bejegyzések listázása egyszerűen PowerShellel

Akik foglalkoztak már a PowerShellel, tudják milyen nagyszerű cucc. Például úgy lehet vele mászkálni a registryben, mint egy mezei meghajtón. Egyedül a kulcsok alatti értékek listázása kicsit macerás, mivel van egy pár property ami általában nem nagyon érdekel minket, mégis belekerül a listába.

Ezek név szerint a PSPath, PSParentPath, PSChildname, PSDrive és a PSProvider. Hogy megszabaduljuk tőlük, nem kell mást tennünk, mint a Get-ItemProperty kimenetét átküldeni egy Select szűrőn:

PS HKLM:\software\microsoft\windows\currentversion\run> Get-ItemProperty . | select * -exclude PSPath, PSParentPath, PSChildname, PSDrive, PSProvider

Igen, ám de ezt elég macera lenne minden egyes alkalommal begépelni. Ezért hozzunk létre egy functiont, ami megcsinálja helyettünk:

PS C:\> new-item -path function: -name Dir-Registry -value {Get-ItemProperty . | select * -exclude PSPath, PSParentPath, PSChildname, PSDrive, PSProvider} 

Ok, mostmár elég annyit beírnunk, hogy Dir-Registry. De mi lusták vagyunk, és ennyit sem szeretünk gépelni. Mit tegyünk? Csináljunk egy aliast!

PS C:\> Set-Alias dirr Dir-Registry

Innentől, ha a registryben járunk, a dir paranccsal a kulcsokat listázhatjuk, a dirrel pedig az aktuális kulcs bejegyzéseit.

Jó mi? :)


Hogyan illesszünk be színes forráskódot a blogunkba?

Hogyan illesszünk be színes forráskódot a blogunkba?

Sokféle módszer létezik, nemrég találtam egy apró praktikát amit most megosztok veletek:
Ehhez szükségünk lesz egy Wordre.

  1. Jelöljük ki a forráskódot a szerkesztőben és másoljuk vágólapra.
  2. Nyissunk meg egy Wordöt és illesszük be.
  3. A Szerkesztés/Csere (Ctrl+H) menüpontban a Keresett szöveg legyen ^p,
    a Csere erre pedig ^l.
  4. Nyomjuk meg az Összes cseréje gombot. Ezzel lecseréljük a <p></p> ket <br/> re.
  5. Nyissuk meg újra a Csere ablakot, most a Keresett szöveg legyen négy darab szóköz,
    a Csere erre pedig ^t.
  6. Nyomjuk meg az Összes cseréje gombot. Ezzel elérjük hogy a behúzások is látszódjanak majd a weboldalon.
  7. Jelöljük ki a teljes dokumentumot, másoljuk vágólapra, majd illessztük be a blogszerkesztőbe. Ne használjuk a Beillesztés Wordből gombot!
  8. Jelöljük ki a beillesztett kódot és nyomjunk rá egy balra igazítást.

Ezek után, ha minden jól ment, megjelenik a szép szines formázott forráskód a blogodban.

Ez eddig szép és jó, de az igazsághoz hozzá tartozik, hogy a behúzások csak addig maradnak meg a forráskódban, amíg a buzz szerkesztőjében el nem mented a művet.

Másik probléma pedig, hogy a Word mindenféle zagyvalékot tesz bele HTML kommentbe. Ez nem lenne feltétlenül baj, mert ugye a komment azért van, hogy azt ne jelenítse meg a böngésző. Normális böngészők nem is teszik, de az Internet Explorer másként értelmezi a komment fogalmát...

Elmentés után, vagy ha be is zártad, akkor a legközelebbi megnyitáskor, a buzz szerkesztő újra olvassa a cikk htmlkódját. Ez még nem is lenne baj, ha úgy olvasná vissza, ahogy elmentette, de sajnos nem úgy teszi.
Ezért ha egy kész cikket szerkesztesz, akkor újból be kell illesztened az összes forráskódot, hogy jól jelenjen meg :/

További jó blogolást!


balinto 2006