» »

Zamenjava Javascripta

Zamenjava Javascripta

Bavec87 ::

Pozdravljeni!

Z Javascriptom sem začel šele pred par meseci in sem v fazi pripravljanja na en večji projekt. Skozi raziskovanje sem naletel na nekaj recimo da svežih člankov npr.: http://www.theregister.co.uk/2011/09/14...
Poglejte si tudi tisti email iz Googla leta 2012.

Seveda mi je zelo pomembno, da pri razvijanju nečesa uporabim najnovejšo tehnologijo, ki je trenutno trend, saj gre zadeva zelo hitro naprej in določene stvari že tako ali tako prehitro zastarajo.

Vprašanje za vas: Ali ste že slišali za programski jezik Dart? Ali mislite, da bo postal trend in kaj kmalu nadomestil Javascript? Ali se bo namesto Darta uveljavil nek popravek Javascripta (npr. Harmony), ki bo kompatibilen z obstoječim Javascriptom? In še zadnje: Ali se splača sedaj implementirati neko rešitev, kar bo trajalo predvideno od pol leta do enega leta z Javascriptom?

Res me zanimajo vaša mnenja. Sicer na Google trends Dart kaže hiter vzpon in tudi hiter padec, samo sem rekel bom vseeno uprašal. Najlepša hvala! :)

Lp Blaž
  • razdelil iz: Mavrik ()

Trinitron ::

Prav gotovo bo javascript ostal še dolgo. Namreč, tudi če se pojavijo nove tehnologije, starih ne morejo zamenjati samo z argumentom napredka. V bistvu prav razvoju pogonov za javascript izdelovalci brskalnikov zadnje čase povečajo še posebej veliko pozornost. Poleg tega se pri večjih projektih lahko zanašaš na knjižnice tipa jQuery, ki precej skrajšajo razvoj javascripta in zagotavljajo vzdržnost kode tudi v prihodnosti.

ZaphodBB ::

Strah me je ko prebiram tvoj post.

Očitno si zelo neizkušen razvijalec in tvoja šola bo izjemno draga, predvsem za tvoje stranke.

Ok, sedaj ko sem opravil z osebnimi napadi pa še tehnikalije. JavaScript ne bo šel nikamor, za to obstaja mnogo razlogov.


Filozofski:

Zdi se mi, da Google sam ne ve kaj bi sploh radi rešili z Dartom. Nekako imam občutek, da se je spet našla čredica Javancev, ki imajo Not Invented Here sindrom.

Tehnični:
Torej, zakaj bi sploh hoteli spreminjati karkoli v JavaScriptu? Res ima par cvetk od bizarnega variable scopinga, štorastega ravnanja s primitivnimi tipi in c-jevske sintakse dalje. Sicer je pa prekleto eleganten jezik. Njegova največja hiba je bila zgodovinsko zgolj to, da je dolgo trajalo da so ga ljudje začeli resno jemat. Skratka z JavaScriptom ni narobe nič hujšega, kar se ne bi dalo popravit skozi evolucijo.

Praktični:
Dart je trenutno eksperimentalen jezik in takšen bo ostal še vsaj pet let. V tem času se lahko prime, lahko ga pa kadarkoli ukinejo. Potem ne pozabi, koliko obstoječe JS kode je zunaj in je ne bo nikoli nihče portal, torej če čez petih let vsa nova koda nastaja v Dartu (nemogoče, a vseeno), lahko komot računaš, da bodo brskalniki takšno ali drugačno podporo JS kodi vlačili za seboj še 10 let (še bolj verjetno pa forever).

Da ne omenjam, da bi s tovrstno odločitvijo uspeh svojega projekta vezal najprej na obstoj projekta Dart (nobene garancije nimaš, da ne bo Larry že čez 3 mesece ukinil projekt) in na poslovni uspeh podjetja Google (iluzija je pričakovati, da bodo konkurenti nov jezik podprli brez "prisile" trga).

Računaj še, da za Dart nimaš knjižnic in orodij, za povrh vsega pa se boš soočal še z najrazličnejšimi bugi in neumnostmi, katere so nadebudni avtorji spregledali.

Takih jezikov se ne uporablja v "večjih projektih", temveč bolj v akademske namene. Svetujem ti, da si prebereš kako je izgledalo življenje razvijalcev, ki so bili prisiljeni biti "early adopterji" Jave.

Brrrrrr.

element ::

JavaScript ima nekaj slabosti, ki se jim z dobro prakso lahko izogneš. Kar ostane je zelo eleganten jezik, ki bo z nami še dolgo. Naslednja verzija, ECMAScript 5, pa prinaša še cel kup novosti in popravlja par največjih zablod, kot so globalne spremenljivke. To bo prihodnost. Glavni problem JavaScripta je ta, da se ga ljudje ne naučijo dovolj dobro. Sintaksa je zelo podobna C-ju in vsak dobi občutek poznanega. Ampak ne bi se mogu obnašat bolj drugače. Ko enkrat dobro razumeš, kako deluje jezik, je zelo ekspresiven.

Bavec87 ::

Hvala vsem trem za hiter reply in uporabne informacije. ;)

Drugače sem že na začetku povedal, da sem šele začetnik, vse kar sem zaenkrat sprogramiral so bili zelo kratki in enostavni programi. Zavedam se, da JavaScript kot jezik ne bo šel nikamor in ga bo browser podpiral tudi čez 20 let. Kakor pa vem razvijalce moti predvsem hitrost procesiranja v delu v browserju, še posebej malo bolj grafično in procesorsko zahtevne stvari kot so zahtevnejše spletne igre in delo s slikami.
Našel sem tale link glede River Trail plugina, ki omogoča paralelno programiranje v JS na eni mašini, na več corih hkrati:
http://www.i-programmer.info/news/167-j...

Naslednja stvar, ki me zanima je ali obstaja kakšna rešitev, s katero bi lahko izvajanje na serverju poslal na več lokalnih računalnikov in paralelno uporabil njihove procesorje za server-side procesiranje. Ukvarjam se namreč s programiranjem simulacijskega programa, ki bo tekel v browserju in bom rabil "horse power". :) Pozna kdo kaj takega?

Lp Blaž

ZaphodBB ::

V glavnem kar se browserja tiče, pozabi na horse power. Računsko zahtevnih zadev se ne računa v browserju, tudi če bi bili JS interpreterji hitrejši.

Preden se preveč razpišemo malo več napiši o sebi. Praviš, da si začetnik - samo v spletnem svetu ali na splošno? Koliko časa že programiraš, koliko izkušenj imaš s programiranjem, optimizacijo, takimi zadevami. Si že kdaj pisal distribuirano kodo?

Tukaj si se podal neposredno v najtežavnejše področje programiranja in ti na tem forumu ne bomo uspeli dolgo pomagati, ti pa lahko pomagamo, da štartaš.

Ne se bat, da ti nočemo pomagat ker si noob. Ampak če si res noob, boš moral sprejet, da pravih konkretnih rezultatov še kako leto ne boš videl, se pa v tem času lahko naučiš, če si iz pravega testa.

element ::

O, pozdravljen sošolec, šele zdaj sem ugotovil, kdo si :). Kot je povedal ZaphodBB se simulacij ne poganja v browserju. Browser lahko uporabiš kot GUI za tvoj simulacijski program, ki teče na serverju. Predlagam ti, da uporabiš JavaScript s HTML-jem le za GUI in Javo za backend, kjer si, če se ne motim, najbolj domač. Ne vem točno kakšno računsko moč potrebujete, ampak že v štartu zakomplicirat zadeve z distribuirano kodo, če ni potrebno je nesmisel. Največjo vlogo pri "horse powerju" ima kvalitetno napisana koda.

Lp, Taj

MrBrdo ::

Najboljši upgrade za Javascript je CoffeeScript (http://coffeescript.org/). Maš compiler ki ti prevede zadevo v čisto navaden javascript, za Railse imaš celo polno integracijo, mislim da je celo default v Rails 3.1.
Vprašanje je samo v tem ali te stvari v Javascriptu dovolj motijo da bi se "učil" nov jezik. Mene ne. Mi pa zgleda vseeno cool Coffeescript.

PS: Mislim da se kaj drugega razen Javascripta še zelo dolgo ne bo uveljavilo. Tako da so take to-js-compiler variante edine smiselne.
MrBrdo

Zgodovina sprememb…

  • spremenilo: MrBrdo ()

garamond ::

Bavec87 je izjavil:

Ukvarjam se namreč s programiranjem simulacijskega programa, ki bo tekel v browserju in bom rabil "horse power". :) Pozna kdo kaj takega?

Mogoče si lahko pomagaš s 3D strojnim pospeševanjem, ki postaja čedalje bolj zrelo. Za grafiko vsekakor, kar se tiče pa računskih operacij pa ne vem (CUDA na WebGL?).
Ampak za široko komercialno uporabo zadeva še ni dovolj dobra, mislim da ima okoli polovica do dveh tretjin povprečnih uporabnikov trenutno to omogočeno (javascript ali Flash), če niso prestari gonilniki. S tem, da Microsoft sploh še ne kaže namenov podpore za to, kar dolgoročno pomeni izbiro Flasha.
Za mobilne naprave pa bo žal potrebna nativna aplikacija z "davkom" nosilcu platforme. Open Web FTW!

arjan_t ::

Za paralelno računananje je že dokaj dobro podprt standard "Web workers", dela se tudi na WebCL

LeQuack ::

Ampak procesorska moč se seli stran od klientov, v "oblak". Javascript pa temelji ravno na tem, tako da ne vem če je to dobra strategija.
Quack !

Isotropic ::

ne, se ne lequack. vsaj za hpc niti pod razno ne.
bavec kaj bi rad simuliral, povej kaj vec.

Bavec87 ::

Živjo Taj, kako gre na Finskem? :)

Lepo, da ste se razpisali. Če hočete razumeti mojo situacijo morate najprej vsaj preleteti moje dodiplomsko delo, ki ga najdete tukaj:
http://dkum.uni-mb.si/Iskanje.php?type=...
Na kratko, delam v Laboratoriju za Kibernetiko in sisteme za podporo pri odločanju na FOV, gre za Javanski simulacijski program, ki vzame nekaj parametrov in skozi večje število iteracij vrne dva parametra. Problem je, ker ta program teče lokalno, rad bi pa, da teče na spletu. Z Javascriptom sem že naredil en zelo enostaven primer web servisa, pri čemer sem uporabil NodeJS. Podaš nekaj parametrov kar v url naslov, saj GUI-a še nisem delal in programček vrne kakšen parameter nazaj, prb. 20 vrstic kode, nobena taka stvar.

Kaj je zdej tukaj želja?
Rad bi, da bi ta program delal v browserju, da za delovanje na client-side ne bi potreboval nič drugega, kaj je uporabnikom najbolj prijazno. Za to imam v mislih, da bi ga najprej prepisal z Jave v Javascript. To bi bila prva faza. Druga faza bi bila, da bi logiko programa razširil z dveh na več dimezij, s tem bi lahko računal rezultat za več stanj, zaenkrat lahko samo dve. Vir za logiko programa že imam, tukaj ne bi smelo biti problema. Da bi ta zadeva delala kot web service je najmanj kar želim doseči, se pravi podaš parametre, dobiš parametre, vendar to je uporabniku zelo nezanimivo, pa še čakati bo moral ob praznem page-u browserja, dokler se zadeva ne izračuna. Ideja je, da bi GUI naredil s pomočjo JSXgrafa, ki bazira na SVG tehnologiji, vektorska slika. Tako bi se v browserju sproti risal graf, pa tudi, če bi bilo izvajanje nekoliko počasnejše bi tako uporabnik lažje počakal. :)

En dokaj lep primer najdete tukaj:
http://www.obitko.com/tutorials/genetic...

Ker kaj takega še nisem zasledil, v laboratoriju mislimo, da bi bila to prava stvar za naše potrebe kakor tudi s poslovnega vidika, poleg tega bi s tega napisal zelo lepo magistrsko delo.

Zanima pa me tudi za nadgrajevanje tega programa, če in ko bo do tega prišlo, zato sprašujem te cluster, multicore zadeve, ker nočem, da je dead end projekt.

Zadeve, ki ste jih predlagali bom pregledal takoj, ko bom imel za to dovolj časa, se pa priporočam za kakršnekoli predloge glede tega kar sem do sedaj napisal, še enkrat vam hvala. :D

Lp Blaž

ZaphodBB ::

Za začetek loči kaj so tvoje dejanske omejitve in težave katere rešuješ ter kaj je tisto kar si želiš narediti.

Tisto kar so tvoje želje takoj eliminiraj s projekta, ker te se bodo spreminjale iz dneva v dan, pač skladno z trenutno modo in tvojim počutjem.

To da delaš simulacije, še ne pomeni, da so računsko zahtevne in da se ti sploh splača razmišljati o muti-threaded kaj šele grid computingu. Kako računsko zahtevno je tvoje delo, veš ti sam. Zavedaj se edino, da velike večine računskih problemov se sploh ne da paralelizirat (izračun faktoriele na primer). Zavedaj se tudi, da je paralelizacija operacije optimizacijski ukrep in ga ne greš izvajat, dokler nisi izvedel drugih optimizacij.

Genetski Algoritmi so sicer fin akademski buzzword, vendar so strahotno počasni, njihova praktična uporaba pa je omejena. Meni se zdi, da bi rad vse buzzworde spravili na kup, pri tem pa se niti ne zavedaš kaj posamični pojmi pomenijo. Mene kar glava boli, ko prebiram kaj bi ti rad izvedel. Pred instantno zblaznitvijo te brani zgolj tvoja lastna ignoranca :D.

Dovolj moraliziranja.

Skratka, če bi rad naredil rešitev, ki deluje in si že izvedel ustrezne optimizacije:
1. Pravi algoritem,
2. Profajling kode in optimizacija,

Lahko začneš razmišljat o sledečih ukrepih:
1. Če se tvoja koda da paralelizirat, jo sparaleliziraš.
2. Po potrebi jo prepišeš v C - to pa zato, da lahko optimiziraš naprej (po potrebi se spustiš v asembler) - vendar dvomim, da si dovolj dober programer za to.
3. Če še ni dovolj hitro začneš gledat kak Fortran.

Da bi zadevo paraleliziral v brskalniku ali pa celo iz jave prevajal v NodeJS je neumnost. To pa zato ker je vse to počasnejše od Jave. Java ali C sta še najboljša splošno dostopni okolji z ustreznimi performancami.

Na tvojem mestu bi zadevo izvedel takole:

UI na brskalniku, zajemaš vhodne podatke in izpisuješ/izrisuješ izhodne podatke.
Na strežniku bi imel dve aplikaciji - spletno storitev in simulacijski program. Spletna storitev je tam samo zato, da igra brokerja med UI in simulacijskim programom (ki je paraleliziran ali pač ne). Simulacijski program izpisuje simulacijske podatke v nek buffer od koder jih WS jemlje in pošilja brskalniku, tu pa potem rišeš grafe oz. whatever.

To velja samo, pod pogojem, da je tvoj problem dejansko računsko zahteven (ob primerni optimizaciji seveda). V nasprotnem primeru, pa ne kompliciraš in vse goniš v brskalniku.

ZaphodBB ::

Ej hvala za info iz prve roke. Me zelo veseli, da gre razvoj aktivno naprej.

Da preverim še enkrat, torej ga uporabljaš na projektih za stranko(e)? Koliko časa? So zadeve že dlje časa toliko zrele? V kakšnem obsegu ga pa uporabljaš?

Morda bi napisal kak blog post o svojih izkušnjah? Saj so starejše objave, ampak lepo je videt informacije, ki niso starejše od pol leta :D

Zgodovina sprememb…

  • spremenil: ZaphodBB ()

MrBrdo ::

JRuby uporabljam predvsem kadar rabim kakšne Java libraryje. Na strežniku sicer uporabljam Ruby EE, zaradi porabe pomnilnika, ker imam VPS. Ker namreč laufam predvsem Rails aplikacije, za katere je EE posebej optimiziran glede porabe pomnilnika (je pa npr. še vedno bolj počasen kot JRuby, saj EE ni optimiziran za hitrost). Osebno bom počakal na EE verzijo 1.9ke, ali morda Rubinius. Je pa JRuby definitivno zrel za uporabo, še posebej je smiselno kadar na strežniku že imaš postavljeno infrastrukturo za gostovanje Java aplikacij. Ni bistveno če sem tisti PDF napisal pred enim letom, ker MRI ni več v aktivnem razvoju (samo security fixi). Tako da primerjava z MRI bi morala biti še vedno dovolj natančna.
Blog sem pa izgubil ker mi je crknil disk, pa se zaenkrat še nisem spravljal še enkrat ga postavljat, ker itak nikoli nisem bil nek uber blogger.
MrBrdo

Zgodovina sprememb…

  • spremenilo: MrBrdo ()

pegasus ::

http://abstrusegoose.com/249 ... ena na temo programiranja :D

Bavec87 ::

Vidim, da bom moral ratat tudi sam bolj programersko pismen, da se bom lahko tudi jaz z vami preganjal, hehe. ;)

Uglavnem, kako procesorsko zahtevno aplikacijo rabim? Tam v diplomski nalogi ste lahko videli, da za število iteracij (ponovitev) obstaja spremenljivka, kar pomeni, da lahko to število določiš sam, več kot je iteracij bolj natančen je izračun. S tega vidika je seveda boljše, da jih je čimveč, se pa pozna na času izračunavanja, razen če delovanje nekoliko pospešimo.

Sedaj, če vas prav razumem mi načeloma predlagate, da simulacijski program pustim v Javi, GUI in izrise grafov sprogramiram pa v NodeJS ter zlinkam med sabo, če je izvajanje zelo zahtevno, drugače je lahko tudi vse v Javascriptu? Sem prav razumel?

Lp Blaž

Gandalfar ::

WebWorkerji se ti ne preslikajo na problem?

Gandalfar ::

When we shared the code with ZeptoLab, they were pleasantly surprised by the performance (particularly the speed and smoothness from the game) that we were seeing in modern browsers. To be honest, we had been holding our breath just a little. We expected JavaScript to be fast but the physics calculations were intense and had to happen in real-time. This is a great example of where common preconceptions about the "slowness" of JavaScript turn out to be wrong. The latest generation of JavaScript engines is incredibly fast.


http://www.cuttherope.ie/dev/

Spura ::

Java Web Start mogoce ustreza temu problemu.

Bavec87 ::

Morem rečt, da sem mal premislu in sem se odloču, da bom šel vseeno prevajat program v Javascriptin sicer zakaj:
- Kode niti ni tako veliko za prevest.
- Javascript je standard, ki se bo obdržal in napisana koda ne potrebuje skoraj nobenega supporta (browser ga bo podpiral še najmanj 20 let).
- Poganjanje Javascripta se bo skozi čas še izboljševalo (že sedaj poznamo kar nekaj enginov npr. V8), tudi Java je bila na začetku zelo počasen jezik.
- Na ta način vse deluje v browserju, tudi programiranje je zelo enostavno, razen če zadeva preraste in se izgubiš :D
- Za grafiko lahko uporabim webGL.
- Omogoča delovanje na širokem spektru naprav kot so PC-ji, tableti, smartphoni itd.
- Na ta način se naučim nov programski jezik, napredek dokumentiram, kar se sklada z raziskovalnim delom na naši fakulteti.

Kakšen komentar na tole mogoče? :)

Lp Blaž

ZaphodBB ::

Glede na to, da svoje okoliščine najbolje poznaš se zdijo tvoji argumenti verodostojni. Na koncu boš pa v vsakem primeru sam živel s posledicami :). Poskusi tako, ker dokler ne boš zares zastavil in že precej naredil itak ne boš vedel kaj so dejanski problemi, torej je nesmiselno preveč komplicirat v tem trenutku.

Spura ::

Bavec87 je izjavil:


- Poganjanje Javascripta se bo skozi čas še izboljševalo (že sedaj poznamo kar nekaj enginov npr. V8), tudi Java je bila na začetku zelo počasen jezik.

To je res v matematicnem smislu. Hitrost JS je nepadajoca funkcija, pocasnejsi ne bo. Zmotno je pa misliti, da imajo razlicni jeziki enake moznosti optimizacije, tako da primerjava s pohitritvami Jave nima osnove. Nekateri jeziki imajo dolocene hitrostne bottlenecke, ki se jih ne da optimizirat stran. Sicer ne vem za JS, vem pa da Clojure naprimer, ne bo nikoli niti priblizno tako performancen kot Java zaradi osnovnih lastnosti jezika. "Optimization will fix the performance gap". Nope.

Bavec87 ::

Hvala fantje! ;)

zdobersek ::

Bavec87 je izjavil:

- Poganjanje Javascripta se bo skozi čas še izboljševalo (že sedaj poznamo kar nekaj enginov npr. V8), tudi Java je bila na začetku zelo počasen jezik.

Nekih velikih optimizacij zaenkrat ni za pričakovat, ker že praktično vsak JS engine opravlja JIT kompilacijo, se pa še vedno da odluščit tu pa tam kakšen procent na določenih primerih kode. Rajši poskrbi, da bo tvoj algoritem čimbolj učinkovit.

Bellzmet je izjavil:

- Za grafiko lahko uporabim webGL.

IE zaenkrat WebGL ne podpira, niti nima načrtov za to.

MrBrdo ::

zdobersek je izjavil:


IE zaenkrat WebGL ne podpira, niti nima načrtov za to.

Za raziskovalno delo praviloma IE nikogar ne zanima ;)

Spura: Nekoč bo :-) Že zdaj se da temu kar približat z JIT in LLVM. Če je dober JIT pol lahko imaš precej ornk performance.
MrBrdo

Mavrik ::

Problem je samo predvsem v tem, da je kombinacija platform, kjer WebGL dela z pol-spodobno hitrostjo precej bedna (na Linuxu itak ne, Maci majo načeloma tudi probleme s performancom... tam je par Chromeov na Windowsih kjer WebGL demoti pridejo do 20 FPS. Na mašini kjer laufa crysis 2 na high s 100 fps.). Long way to go.
The truth is rarely pure and never simple.

ZaphodBB ::

@Mavrik: on rabi grafiko, ne pa Crysis

Gandalfar ::

Naj vzame flash oz. svg potem ane. Saj vejretno vektorje rise, ne neke fancy 3d bitne zadeve.

Mavrik ::

ZaphodBB je izjavil:

@Mavrik: on rabi grafiko, ne pa Crysis


Saj "grafika" je tista ki deluje tako počasi. Probaj ;)
The truth is rarely pure and never simple.

ZaphodBB ::

Nekaj sem probaval, pa se mi je zdelo čisto kul glede na to, da je zadeva še jako v povojih. Zato se pa usajam :D

ZaphodBB ::

Je bilo govora o brzini, pa so se norca delali iz mene ko sem nekaj o Fortranu govoril.

http://shootout.alioth.debian.org/u64q/...

MrBrdo, od kje taka razlika boš pa ti vedel kaj več povedat - glede na to da sta oba jezika prevedena v strojno kodo?

p.s.: zanimiva debata http://news.ycombinator.com/item?id=345...

Zgodovina sprememb…

  • spremenil: ZaphodBB ()

MrBrdo ::

Zanemarljiva razlika... Sicer pa je čisto odvisno od aplikacije do aplikacije. Raje si tule poglej: http://shootout.alioth.debian.org/u64q/... Večinoma so časi enaki, če pa že pogledaš razliko pri posameznih primerih boš pa videl tam primer ko je bil Fortran celo 25x počasnejši. O tem niti nima smisla debatirat, to so neki mejni primeri za katere prevajalnik pač ni ali pa je optimiziran. V teoriji bi morala imet jezika enak performance. Pa tudi v praksi sem ziher da imata v povprečju zelo podobnega, kot je tudi mogoče sklepat iz gornjih rezultatov. Razlika je samo v tem da je v Cju za večino lažje programirat.
MrBrdo

Zgodovina sprememb…

  • spremenilo: MrBrdo ()

Mavrik ::

Mavrik je premaknil sporočila v [Debata] JavaScript in jeziki z prototipnim dedovanjem.

// Da ne bomo več smetili te teme ;)

Zgodovina sprememb…

  • spremenil: Mavrik ()


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Oracle opušča Java Plugin

Oddelek: Novice / Brskalniki
4121044 (18347) andromedar
»

Kaj prvo PHP ali Javascript (strani: 1 2 )

Oddelek: Izdelava spletišč
779337 (7945) HardFu
»

Bi delali igro?

Oddelek: Igre
294206 (2903) blackbfm
»

[Debata] JavaScript in jeziki z prototipnim dedovanjem (strani: 1 2 )

Oddelek: Programiranje
516976 (6842) zigomir
»

Quake 2 v HTML5, novosti v Chrome 5

Oddelek: Novice / Brskalniki
2510052 (8845) arjan_t

Več podobnih tem