All posts in “Programozás”

PHP: az in_array() lassú!

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ú!

Javascript: regex_match_all()

Egy Stack Overflow-n feltett kérdésre kerestem a választ. Az ottani problémát kb. így lehetne leegyszerűsíteni:

Ki lehet-e nyerni egy globális regex mintaillesztés esetén a zárójelbe tett értékeket minden találatból?

Hát ki lehet, de nem egyszerűen. Problémák:

  1. Először is erre nincs egy kimondott függvény, tehát meg kell keresni ezek megfelelő kombinációját. A pattern.exec(text) szépen visszaadja a zárójelezett részek tartalmát egy tömbben, viszont csak az első teljes találatét. A text.match(pattern) pedig megtalálja a teljes minta minden előfordulását, viszont csak ezeket adja vissza egy tömbben. No, de hát ez remek, hisz ennek a kettőnek a használatával megvalósítható a dolog.
  2. Akkor hozzunk létre egy RegExp objektumot és ezzel futtassuk a fenti függvényeket. Igen ám, de egy regex minta objektumot csak egyszer tudtam felhasználni. Ha egyszer matchelt valamire, akkor ugyanaz a minta objektum már null-t adott minden további kísérletre. Erre is van megoldás, minden mintaillesztés előtt új objektumot kell létrehozni egy szövegesen tárolt minta alapján.

Végeredmény az alábbi kód, ami paraméterül várja a szöveget (text), amiben keresünk, a mintát (pattern) és a módosítókat (mod), amik viszont csak “i” és “m” lehetnek, mivel a “g”-t használja a függvény.

1
2
3
4
5
6
7
8
9
10
11
12
13
function regex_match_all(text,pattern,mod) {
    mod = mod ? mod.replace(/[im]/,"") : "";
    var i, max, all = [],
        re = new RegExp(pattern, "g"+mod),
        match = text.match(re);
    if (match) {
        for (i=0, max=match.length; i<max; i++) {
            re = new RegExp(pattern, ""+mod);
            all[i] = re.exec(match[i]);
        }
    }
    return all;
}

A kimenet sikeres találat esetén egy tömb, aminek minden eleme egy újabb tömb, amikben rendre megtalálhatóak: a teljes találat és a zárójelezett résztalálatok sorrendben egymás után.

CSS::selection

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?

Letöröltem!!! ÁÁÁÁÁÁÁÁ

Ma éjjel 11kor, a leadási határidő előtt egy órával megtörtént velem, minden programozók rémálma, két napi munkám veszett ma oda, mert véletlenül letörötltem. Igen a Backuppal együtt. Most épp a Data Recovery dolgozik az ügyön, de Istenre esküszöm, ha nem lesz meg akkor újraírom, csak lehessen még akkor leadni. Egyébként meg:

A BÜDÖS ÉLETBE, HOGY ILYENNEK MÉRT KELL TÖRTÉNNIE!!!???

KoInKuT

Kossuth, Inti, Qbi (Kubi) és Tücsi

Ez a kis csapat, és a név egy pozitív élmény volt életem elmúlt tizenegy hetében. Szeptember közepe volt már, mikor is végre kialakult, hogy mi négyen együtt fogjuk ebben a félévben csinálni a Számítógép-Labor 4 nevű tárgyat. A követelmény, hogy a kiírásban szereplő programot, megadott ütemben, részletesen dokumentálva kell elkészíteni, maximum 4 fős csapatokban. A feladat a következő volt (a kiírás menet közben megváltozott, az a szerinti végleges változatot írom most ide):

Egy gömb felületű világban mozog a Nagy Térgombolyító (a nagy sárga gömb), és menet közben térgombolyagokat (a kis rózsaszín gömbök) gombolyít le magáról. Az űr ezen szegletében portyáznak a varangyhajók (zöld gömb), akik féregjáratokon érkeznek és gyűjtögetik a térgombolyagokat, valamint itt vannak még az emberek (kék gömb), akik szintén a gombolyagokat akarják. A pályán elszórva vannak még hiperűrcsövek, melyek mindkét irányba járható féregjáratok (kék körök, melyeket vonal köt össze).
A játékos az egérrel kiválaszthatja és irányíthatja a hajókat, így felvehet gombolyagokat, és nekimehet a varangyok hajóinak. Ez csak abban az esetben nem végzetes, ha van nálunk térgombolyag, akkor egy gombolyagért cserébe mi megmenekülünk. Körülbelül ebben ki is merül a játék, ami addig tart míg van hajónk.

A fejlesztésnek négy szakasza volt. Egy modellezés, mikor kitaláltuk, hogy is fogjuk ezt megcsinálni, aztán ennek a vázát leprogramoztuk, majd jött a prototípus, és végül a grafikus felület. A végső változatról készült screenshot egy részlete látható oldalt. Fentebb a specifikációban ennek megfelelően jeleztem, hogy mi micsoda. A programozás életem hosszú óráit követelte: a protót 16, a grafikust 20 óra non-stop programozás eredményeként sikerült megcsinálni, de megérte. Komolyan mondom megérte, élveztem csinálni, és mikor a finisbe értem nagyon klassz érzés volt. Működött, és nem is akárhogy. Ugyan ez a kis kép nem adja vissza az animált részeket, meg a játék hangulatát, de az hogy 10, 100, és 200 pontonként eltoltuk már ketten is 23000 fölé, az azért jelent valamit. Megjegyzetm, mi akik fejlesztettük nyilván szivesen játszottunk vele, egy játékkal – itt a százszámra megjelenő 3D-s csoda között – amit mi csináltunk, ez egy különösen jó érzés.

Klassz kis projekt volt, a konzulensünk megdícsért minket, az eredményt pedig hamarosan megtudjuk, de addig is: Project KoInKuT Finished.

Pusztuljon az IE

browser { live: yes; *live: no; }

Ugyan az oldalt látható kis kép elkészítése során már kiadtam a gőz nagy részét, de ma komolyan elszállt az agyam az IE-től. Jönnek az egyik osztályról, hogy az új design óta az egyik oldal nem nyomtatható ki helyesen, mert elcsúsznak a szövegek. Hát gratulálok, újabb IE szopás, ugyanis a nyomtatási nézet megjelenítő motorja nem ugyanaz, mint az oldalé, így nem jelennek meg helyesen a div-ek…

…közben elszólított a munka. Nos, felvéve az elejtett fonalat, elkezdtem hekkelgetni az oldalt, és kiderült, hogy van egy kis 2 pixeles csalás valahol egy div mellett, amibe “beleakad”, de most komolyan, be-le-akad egy alatta lévő div. padding: 2px; beszúr, oldal helyreugrik, zsír. Firefox: szöveg egymáson, hullámokban jön a agyroham, pici * beugrik a padding elé, és már is minden ok.

Ülök a széken, az az orvos aki bennehagy valamit a betegben, de az utolsó pillanatban észreveszi és kiveszi, na ő valami hasonlót érezhet, bár ugye itt kisebb a tét. Ettől függetlenül rohadjon meg az Internet Explorer, hogy állandóan hekkelgetni kell, hogy jó legyen. Ennek tetejébe, a minap mesélte valaki, hogy a 7-esben “szándékosan” nem fogják a szabványokat követni. Hát még jó, hogy teleaktivikszolhassák a szerencsétlen felhsználó fejét, na de ez még a jövő baljós szele… pletyka… remélem az is marad.

A hosszú napok vége

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…

A 35. óra

Nem tudom már sokáig ébren. Egész éjjel JAVA-ztam, és még a közgáz se sikerült…