Subscribe to Rss Feed : Rss

Üdv!

Majd itt lesz valami...

PHP: az in_array() lassú!

Filed Under (Informatika, PHP, Programozás) by inti on 21-06-2011

Volt egy érdekes problémám, vagy inkább idegesítő.

Arról van szó, hogy egy hírlevél küldő rendszerben az első lépés a címek kigyűjtése. Az én esetemben ez úgy nézett ki, hogy nagyjából 8000 visszaigazolt címet kellett összevetni az összesel (22000), kiválasztani a visszaigazolás óta ($fix_datum) bekerülteket valamit a visszaigazoltakat. Semmi gond. Létrehoztam egy $confirmed tömböt a visszaigazoltakból, majd szépen végigsétáltam az összesen és teszteltem:

if ($email_datum >= $fix_datum
 || in_array($email_cim,$confirmed))
{ /* ... */ }

Mi volt ezzel a baj? Hogy 10 másodpercig futott! Ez rendkívül idegesítő, főleg ha a hírlevél kezelőben is lefut, mikor szerkesztem. Na tennem kellett valamit. Első gondolatom az volt, hogy az email címek első X karakterei szerint kisebb tömbökre darabolom a visszaigazolt címeket. Nyilvánvaló volt, hogy a 8000 elemű tömbben való keresgélés a gond.

if ($email_datum >= $fix_datum
 || (!empty($confirmed[$keys])
  && in_array($email_cim,$confirmed[$keys]))
{ /* ... */ }

Az eredmény nem maradt el. X = 1 esetén 10-szeres, X = 2 esetén 32-szeres, X > 3 esetén pedig több, mint 70-szeres gyorsulás volt tapasztalható.

Feltételeztem, hogy egy ponton megfordul ez tendencia, szóval engedve a kisördögnek, elkezdtem feszegetni a határait. Nyilván nagyon nagy számot nem lett volna értelme megadni, mivel az e-mail címek mérete korlátozott, vettem tehát a legdurvább esetet, gyakorlatilag megfordítottam a tömbömet. A címek lettek a kulcsok, értéknek meg kapott mind egy true-t.

if ($email_datum >= $fix_datum
 || isset($confirmed[$email_cim]))
{ /* ... */ }

És jött a meglepetés! 100-szoros gyorsulás! Bizony, egy több ezer elemű tömbben a kulcsra való tesztelés 100-szor gyorsabb, mint az in_array().

A kísérletekből visszamenőleg látszik, hogy minél nagyobb számú X szerint bontottam a tömböt, annál kisebb altömbökön futott az in_array(), közben persze folyamatosan lépett be a kulcskeresés, amikor hivatkoztam az altömbökre ($confirmed[$keys]), míg végül csak az maradt.

Levonhatjuk tehát a tanulságot: nagy tömbök esetén az in_array() lassú!

CSS::selection

Filed Under (CSS, HTML, JavaScript, jQuery, PHP, Programozás) by inti on 02-06-2010

Ma reggel IT chaten megjelent egy link (http://fichtre.net/yop.html). Az oldalon a Ctrl+A billentyűk lenyomására kirajzolódik egy kép. De hogy?

A probléma két részből áll:

  1. határozzuk meg egy kép pontjainak színét
  2. hogy tegyük ezeket láthatóvá a Ctrl+A billentyűk lenyomására

Először is tudnunk kell, hogy egy képen az egyes képpontok milyen színűek. Ezt pedig a PHP GD moduljának segítségével lehet kideríteni. Miután beolvastuk a képet, végiglépkedünk a képpontokon, majd az imagecolorsforindex() és imagecolorat() függvényekkel megkapjuk a képpont színét adó 3+1 (piros, zöld, kék + alpha) komponenst egy tömbben. Mikor ezt végiggondoltam jutott eszembe, hogy ezt a részét én már egy éve megcsináltam egy kis délutáni kísérletezgetés alkalmával.

Itt említenék meg egy fontos apróságot. Átlátszó PNG képek esetén vannak ugye alpha komponensek. Ezt úgy kell elképzelni, hogy ahol a képen a látható tartalom és az átlátszó háttér találkozik, ott valójában folytatódnak a színek, csak a képpont átlátszósága változik. Ezt a komponenst kapjuk meg az alpha értékben, és ebből egyszerű százalékszámítással adódik az a 0 és 1 közötti szám, mellyel ezeknek a képpontoknak az átlátszóságát kell meghatározni. Erre egy apró jQuery kódot használtam.

A képpontok helyére karaktereket tenni nem különösebb probléma. Én egy 3 bekezdésnyi lorem ipsumot generáltam, és azt végtelenítettem. Az külön szerencse, hogy a fix szélességű Courier New betűtípus két karaktere pont egy négyzet alakú területet foglalnak el.

Na hát, ha már a fele megvan, akkor csak megcsinálom az egészet. Gyorsan utána néztem, hogy is működhet a probléma másik része, vagyis, hogy kijelölésre kapnak színt az egyes betűk. A trükk egy CSS pszeudoállapot, nevezetesen a ::selection. Ez a CSS3 szabvány része, és mint sok ilyen, megtalálható a mozilla böngészőkben ::-moz-selection néven is. Ez a selector az elem azon állapotát határozza meg, mikor a benne található szöveget kiválasztjuk. Meghatározhatjuk benne a szöveg és a háttér színét is. A “csoda” pedig úgy lesz ebből, hogy az egyes betűk, mind egy-egy elem, melyeknek meg van határozva, hogy kiválasztáskor milyen hátterük és szövegszínük legyen, végül pedig Ctrl+A: Minden kijelölése.
(Tobábbi részletek és példa a selectorról: http://www.quirksmode.org/css/selection.html)

Minden adott volt hát, az első verzió pedig nagyjából 20 perc után már működött is. Ezzel viszont az volt a baj, hogy csak a célra törekedtem, így majdnem 1 MB lett a kimeneti HTML oldal egy 64×64 pixel méretű képecske esetén, 100×100 képpont felett pedig már a Firefox kezdte megadni magát, mikor 10000+ elem hátterét kellett volna megváltoztatnia egyszerre. A kimenet méretét további finomhangolással sikerült a harmadára csökkenteni, így lett kész a végleges változat: http://intiweb.hu/dev/ctrla/

A dolog, mint az a fenti képen is látható, nem teljesen böngésző független. Az Internet Explorer természetesen renitens a CSS3 elemek implementálásában, így még a 8-asban sincs lehetőség a kiválasztott szöveg paramétereinek módosítására. Szégyelljék magukat… pedig ez milyen hasznos funkció, nem?

A hosszú napok vége

Filed Under (Élet, CSS, Freeblog, JavaScript, Munka, PHP, PSP) by inti on 02-12-2005

1. fejezet
Egy project vége… egy új design kezdete

Régóta nem írtam már. De ennek meg volt az oka. E hét kedden és szerdán simán a fél napomat a cégnél töltöttem, élesítés előtti hajrá.
Aztán szerda este háromnegyed nyorlckor felmásoltuk az új designt, és… hip… hop… fél 11kor már mentünk is haza. A project jól sült el, az oldal most működik, ugyan kellett hibákat javítgatni, de most már nagyjából okés.
2 hónapig dolgoztam rajta. A fejlesztési idő alatt többször is előfordult, hogy estig dolgoztam, főleg az elmúlt 1 hónapban, de végül időben kész lett.
A látogatók számára a design a mellékelt képen látható mértékben változott, viszont az oldalakat generáló háttér sokkal inkább.

A nem hozzáértők nyugodtan ugorjanak a következő fejezetre, szakmai blabla következik:

A lekerekített kereteket egy nifty corners nevű javascript+css kombinált technológiával alakítottam ki, az oldalakat pedig a PHP Smarty template motor generálja, ami ugyan nem újdonság az oldal történetében, de most a Smarty lehetőségeit még
jobban kihasználja. Ezen felül a table-layout majdnem minden oldalon fel lett számolva, legalábbis a dobozok elrendezéséért már a css+div felel, azért viszont, amit egy doboz tartalmaz már nem kezeskedem. Sajnos a megjelenítés terén fejlődniük kell még a böngészőknek, ugyanis nem volt olyan, amelyik a körbefolyatott objektum magasságát figyelembe véve megnyújtotta volna az őt tartalmazó div konténert, de hát megoldottam valahogy ezt is. Külön öröm, hogy az egyik aloldalon becsempésztem egy kis AJAX scriptet az oldalba, ezekből hamaroan több is lesz.

2. fejezet
A PSP

Időre elkészült projecteknek, egy ilyen klassz munkehelyen, mint az enyém, velejárója a prémium. És az első fejezet tanulságát behelyettesítve a képletbe

ha (project_kesz) akkor prémium;

egyértelmű, hogy kimondottan boldogan hagytam el tegnap délután a munkahelyem.
Irány a Westend, OTP fiók. Megnyomom a gombot a cetli-o-matán… túl sok itt az ember …vároma cetlit… dec. 1. csütörtök …jön a cetli, 189… fizetés nap!!! …a tábla szerint épp most hívták a 174-es ügyfelet. Rendben semmi gáz. Leültem és közel fél órát vártam míg végre sorra kerültem. Eközben az összes apró banki konfliktust részem volt látni: tolakodás, variálás, bliccelés, stb. Miután befizettem a pénzt a számlára, elindultam haza, és az alsó szinten elkövettem azt a hibát, hogy bementem az 576-ba.
Ott volt. Ellenállhatatlanul hívogatott. Körülnéztem, kimentem. Elindultam a kijárat felé, de hirtelen azon kaptam magam hogy ismét az üzlet felé tartok. Ez még 3-szor előfordult, és ekkor feladtam. Bementem, kértem, kaptam, vittem, jöttem, láttam, győztem. (A pultnál egy buzgó srác, épp nagy odaadással nézegette a demóvideókat a kirakati darabon, és baromságokat kérdezett, pl.: – van Bluetooth rajta? – Nincs, de van Wi-Fi. – És az kombinálható Bluetooth-szal?)
A szatyromba belekerült még az NFS Most Wanted, meg egy ilyen gumikarperec, amiből ugyan hordok egy ARC plakátkiállításosat, de többet semmiképp nem viselnék. Na jelen darab 576 felirattal volt díszítve, és valószínűleg 12-éveseknek készült, mert valami hihetetlenül kicsi volt. Szánalmas ez a karkötő tendencia, mikor a fél karján végig gumi… na mindegy, erről majd máskor.
A hazafelé útról meg csak annyit, hogy: 220 és 284.

3. fejezet
Véremet vették

6:30 – ébredés, ááárgh! Fény!!!
7:08 - ülök a váróban, az ajtón ez áll Laboratórium.
7:16 - leülök a székre. Szemben lehet egy ajtó, de nem látom rendesen, egy nő van előttem. Simán nagyobb mint az ajtó, kedvesen mosolyog, és kéri hogy tegyem szabaddá a karom.
7:20 – Pár decivel kevesebb, de megérzem. Én meg. Picit fáj is a helye.
Felfelé a buszon Most Wanted-oztam picit. Hihetetlen jó dolog ez a PSP, gyönyörű kép, könnyű kezelhetőség. Mikor elraktam (3/4 óra Most Wanted és -9% az akku, hejj, ez jó cucc) egy srác, aki közben mellém ült megböki a vállam. “Mennyi egy ilyen kütyü?” – kérdi, és egész Népligetig szóval tartott. Azt mondta vagyonőr, épp munkát keres. Érdekes egyszerű felfogása volt dolgokról. Remélem bejött neki a meló.
Ezek után a mai nap volt ez eddigi legnyugisabb munkanapom, bár lehet hogy csak az elmúlt hetek fényében mondom ezt. Az oldal működik, a hagymaleves is. Varázsolja a dolgokat a gyomromban… hú a varázslásról szólva.

Szereztem egy moziműsort a Westendben és mit látok: Harry Potter, és a Tűz Serlege, szinkronos, szünettel!!! 157 perces a film, Jézusom, bár meglepődésre semmi ok, az eddigi filmek másfél órájához képest az alapul szolgáló könyvek mérete világosan adta, hogy ennek hosszúnak kell lennie. Még nem láttam a filmet, de már vároma következő részeket!

Epilógus

Hát, azt hiszem, szép kerek kis post lett ez. Hamarosan újra jelentkezem…