• No results found

Optimeringsstrategier för en sökalgoritm i javascript

N/A
N/A
Protected

Academic year: 2021

Share "Optimeringsstrategier för en sökalgoritm i javascript"

Copied!
101
0
0

Loading.... (view fulltext now)

Full text

(1)

OPTIMERINGSSTRATEGIER FÖR

EN SÖKALGORITM I JAVASCRIPT

OPTIMIZATION STRATEGIES FOR

A SEARCH ALGORITHM IN

JAVASCRIPT

Examensarbete inom huvudområdet Datalogi

Grundnivå 30 högskolepoäng

Vårtermin 2015

Linus Berglund

(2)

Sammanfattning

Det blir allt vanligare med att använda webbläsare som plattform för applikationer istället för de konventionella som måste installeras lokalt. Frågan är hur pass bra JavaScript står sig när det kommer till intensiva och tunga algoritmer såsom sökalgoritmer för spel. Finns det optimeringar som kan förbättra tidsåtgången för sökalgoritmer så att användaren i slutändan inte tröttnar på att det tar för lång tid? Med hjälp av ett antal tekniker såsom Typed Arrays försöker det här arbetet påvisa huruvida Typed Arrays kan användas som optimeringsstrategi för en applikation handskriven i JavaScript för att sänka tidsåtgången.

Detta arbete syftar till att utvärdera hur användbart av optimeringsstrategier såsom Typed Arrays påverkar tidsåtgången för en förutbestämd sökväg. Flera versioner av en applikation implementeras för att se vilken optimering som är mest lämpad och utvärderas sedermera genom prestandamätning. Resultatet visar att ingen av de valda optimeringsstrategierna gav någon nämnvärd förbättring utan var till vissa delar en försämring jämfört med referensmätningen.

(3)

Innehållsförteckning

1

Introduktion ... 1

2

Bakgrund ... 2

2.1 Sökalgoritm ... 2

2.2 Dynamiskt typade och statiskt typade språk ... 3

2.3 Optimering av JavaScript ... 4

2.4 Problem med JavaScript ... 4

2.5 Arrayer i JavaScript ... 5 2.6 Typed arrays ... 6

3

Problemformulering ... 7

3.1 Problemet ... 7 3.2 Hypotes ... 8 3.3 Metodbeskrivning ... 9 3.3.1 Experiment ... 9 3.3.2 Alternativa metoder ... 10 3.3.3 Metoddiskussion ... 10 3.3.4 Forskningsetik ... 11

4

Genomförande ... 12

4.1 Förstudie ... 12 4.2 Progression ... 12 4.2.1 Implementera grunden ... 12

4.2.2 Optimering array för rutnät ... 15

4.2.3 Optimering array för vägar ... 17

4.2.4 Optimering Typed arrays ... 20

4.2.5 Automatisering av applikation ... 21

4.3 Pilotstudie ... 22

4.3.1 Utan optimeringsstrategi ... 23

4.3.2 Typed arrays ... 23

5

Utvärdering... 25

5.1 Plattformar, hårdvaruspecifikation och parametrar för testning ... 25

5.2 Resultat ... 27

5.2.1 Referensmätning (V2) ... 27

5.2.2 Optimering array för rutnät (V3) ... 29

5.2.3 Optimering array för algoritm (V4) ... 32

5.2.4 Optimering Typed Arrays (V7) ... 34

5.3 Analys ... 36

(4)

1

Introduktion

Webben växer allt mer för var dag som går och har blivit en allt större plattform även för utvecklare när det kommer till att utveckla nya former av applikationer. Mherara, Hsu, Samadi & Mahlke, (2011) tar bland annat upp att utvecklare förflyttar avancerade beräkningar från server-sidan till klient-sidan för att dels minska nätverkstrafiken men också för att förbättra applikationers responsivitet.

Många av dessa applikationer är skrivna i JavaScript eftersom JavaScript är ett välkänt dynamiskt skriptspråk för webben. Dessa applikationer tenderar att öka i storlek beroende på hur beräkningsintensiva och komplexa de blir vilket medför högre krav för att förbättra deras prestanda (Mherara, Samadi & Mahlke, 2011).

Khan, et al. (2014) tar bland annat upp att JavaScript får en allt mer ökad support och standardisering i flera moderna webbläsare (ex. Chrome, Firefox, Safari). Detta ger utvecklare en väldigt enkel men också användbar kanal för att distribuera sina applikationer till långt fler användare eftersom de flesta idag använder någon form av modern webbläsare i sina datorer eller mobila enheter.

Mehrara & Mahlke (2011) skriver att det idag redan finns många ansträngningar för att utveckla spel i JavaScript för att sedan kunna köras på webben. Eftersom dessa applikationer domineras av ett frekvent antal loopar och funktioner så är det dessvärre vanligare att dessa applikationer är skrivna i ett mer statiskt typat språk. Varför det är så beror till stor del på att konsumenter inte accepterar alltför dåliga resultat som det innebär att ha dem implementerade i JavaScript.

Frågeställningen som undersöks i det här arbetet är ifall det är möjligt att påskynda svarstiden för en känd sökalgoritm med hjälp av optimeringsstrategin Typed Arrays samt om Typed Arrays kan användas till annat än enbart algoritmer. Hypotesen är således att Typed Arrays som optimeringsstrategi kommer att sänka svarstiden för sökalgoritmen A* jämfört med samma algoritm fast utan optimeringar implementerade.

För att svara på de frågor som ingår i frågeställningen så har experimentmetoden tillämpats för det här arbetet då det ansågs vara den bästa metoden för att ge svar på de frågor som ställts. Sedan konstruerades ett flertal olika varianter av en och samma webbapplikation där varje variant implementerade någon form av optimeringsstrategi. Likvärdigt för alla optimeringsstrategier är att de optimerar på samma del av huvudapplikationen men att det sedan sker på olika sätt beroende på optimeringsstrategi.

Huvudapplikationen som sådan är skriven i JavaScript där en implementerad version av sökalgoritmen A* används. En spelplan med ett fördefinierat antal hinder används sedan för att sätta algoritmen på prov samtidigt som det även finns en kontrollpanel för att enkelt kunna utföra mätningar.

(5)

2

Bakgrund

2.1 Sökalgoritm

Khan, et al. (2014) tar i sitt arbete upp att JavaScript används i allt större utsträckning för att köra 3D-spel och andra former av numeriska beräkningar i en vanlig webbläsare. För det här arbetet kommer därför en sökalgoritm kallad A* (A-star, hädanefter A*) att användas vilket skall representera en vanligt förekommande algoritm i spelutveckling (Cazenave, 2006).

A* är en sökalgoritm som försöker finna den minst kostsamma vägen från en given startpunkt till en slutpunkt (Ajwani & Meyer, 2009, 27). A* beskrevs första gången av Peter Hart, Nils Nilsson och Bertram Raphael 1968. Den är i grund och botten en förlängning av Edsger Dijkstras algoritm från 1959 där skillnaderna dem emellan är framför allt att A* uppnår bättre tidsprestanda genom att använda sig av heuristik (inom datavetenskap är heuristik en teknik för att lösa problem snabbare på bekostnad av annat) (Hart, Nilsson & Raphael, 1968).

Zou, et al. (2010) skriver bland annat att eftersom A* är en heuristik sökalgoritm så innebär det att den använder heuristisk information för att välja den mest lovande noden (knutpunkt) för att expandera sig vilket förbättrar sökeffektiviteten avsevärt. Dessutom består A* av två olika listor, en öppen och en stängd, där den öppna lagrar de noder som algoritmen måste expandera till medan den stängda lagrar de redan expanderade noderna. A* använder sig av värdet av f(n) för kostnadsfunktionen f(n) = g(n) + h(n) som sökorienterare. När den expanderar så kommer den välja den nod som har minst värde av

f(n) där f(n) är den minsta kostnaden från startnoden till målnoden genom noden n medan g(n) representerar kostnaden för vägen från startnoden till vilken vertex n som helst, h(n)

representerar den estimerade heuristiska kostnaden från vertex n till målnod (Zou, et al., 2010).

(6)

Ett exempel kopplat mer till hur A* skall användas i det här arbetet visas i Figur 2 där exemplet visar hur A* används för att komma runt ett hinder och fram till målnoden G. Den utgår från startnod S och expanderar sedan genom O som representerar den öppna listan medan C representerar de noder som redan har blivit expanderade och försatta i den stängda listan. P representerar den mest optimala vägen fram till målnoden G efter slutförd exekvering. Detta exempel presenteras i Zou, et al. (2010) arbete.

Figur 2 Visar en interaktiv graf där A* används

2.2 Dynamiskt typade och statiskt typade språk

Dynamiskt typade språk, exempelvis PHP och JavaScript, växer i popularitet på grund av deras höga produktivitet och enkelhet när det kommer till programmering. Förutom detta så erbjuder de även en flexibilitet, hög nivå av datastrukturer, interoperabilitet med andra språk samt en rik uppsättning av ramar och bibliotek. Detta bidrar till den ökade produktiviteten och anledningen till varför dessa språk har blivit speciellt lyckade för applikationer anpassade för webben (Ishizaki, Ogasawara & Castanos, 2012).

Tyvärr så bidrar även samma flexibilitet till att utvecklare står inför svåra utmaningar när det kommer till att effektivisera kod och även när det kommer till optimering, där framför allt optimering är något som utvecklare försöker tillämpa i en allt större utsträckning för att förbättra prestandan (Ishizaki, Ogasawara & Castanos, 2012).

”Dynamically-typed object-oriented languages please programmers, but their lack of static type information penalizes performance” (Chambers &

Ungar, 1989)

Vilket är ett citat som stämmer väl överens med verkligheten även idag när det kommer till dynamiskt typade språk. Chambers & Ungar (1989) skriver vidare att dynamiskt typade objektorienterade system historiskt har lidit av dålig prestanda jämfört med ett statiskt typat språk såsom C. Bolz, Diekmann & Tratt, (2013) tar även upp att dynamiskt typade språkimplementationer exekverar långsammare samtidigt som de använder mer minne än sina statiskt typade motsvarigheter, vilket dels beror på avsaknaden av optimering.

Mehrara, Hsu, Samadi, & Mahlke (2011) tar bland annat upp en mätning där de undersöker hur stor prestandaskillnad det är för en given algoritm skriven i både dynamiskt och statiskt typat språk. Mätningen påvisade bland annat att algoritmen implementerad i ett dynamiskt typat språk såsom JavaScript var så mycket som 50x långsammare än samma algoritm

(7)

2.3 Optimering av JavaScript

Ishizaki, Ogasawara & Castanos (2012) tog som sagt upp att JavaScript är väldigt produktivt och framför allt flexibelt men att det sker på bekostnad av att utvecklare har stora utmaningar när det kommer till att öka prestandan i JavaScript, vilket ofta sker genom optimeringar.

Khan, et al. (2014) försöker i sitt experiment öka prestandan i en handskriven JavaScript applikation genom att byta ut de vanliga arrayerna mot speciella typer av arrayer, så kallade typed arrays. Det visade sig efter utfört experiment att denna optimering gav signifikant förbättring prestandamässigt för applikationen jämfört med samma applikation skriven med vanliga JavaScript arrayer.

Eftersom det här arbetet till viss del kommer innefatta replikering av Khan, et al. (2014) och deras arbete så kommer typed arrays att användas som en optimeringsstrategi för att se om liknande resultat kan uppnås i det här arbetet.

2.4 Problem med JavaScript

JavaScript har tyvärr ett antal brister på grund av den dynamiska typningen där framför allt att inga variabeltyper deklareras någonstans. Hackett & Guo (2012) tar i sin studie upp ett exempel (figur 3) där de visar ett enkelt program skrivet i JavaScript, och vad de vill visa är att det endast deklareras variabler av olika typer. Genom att läsa av koden så ser man att det deklareras ett antal variabler, exempelvis res och a, vilket visas genom att de båda har var framför sig. Problematiken med att enbart deklarera variabler och inte variabeltyper är att JIT-kompilatorn inte vet vilken typ variabeln består av, om den är en sträng eller ett heltal, vilket innebär att kompilatorn måste skicka med onödig kod (overhead) för att hantera alla möjliga kombinationer av typer (både för strängar, heltal & alla andra typer). När värden kopieras fram och tillbaka så måste kompilatorn skicka med kod för att hålla reda på typerna för de involverade värdena, där den kan använda antingen en separat typ-tag eller ett specialiserat format. Detta innebär att det blir väldigt mycket overhead för den genererade koden.

(8)

innehålla flera värden av olika typer men det kan också finnas arrayer av samma typ. Om man däremot visste vilka typer res och a hade, då skulle man kunna kompilera koden utan att först söka efter vilken typ det handlar om vilket resulterar i att kompileraren i många fall kan generera kod som efterliknar statiskt typade språk.

Bolz, Diekmann & Tratt (2013) tar i sin studie bland annat upp att dynamiskt typade språkimplementationer använder mer minne samt exekverar långsammare än en statiskt typad språkimplementation. Ofta beror detta på att operationer på samlingar av element är ooptimerade.

2.5 Arrayer i JavaScript

För att få en ökad förståelse för vad typed arrays är och hur de fungerar så är en bra början att förklara vad vanliga arrayer i JavaScript används till och hur de fungerar. Kortfattat kan man säga att de används när man vill förvara multipla värden i en enda variabel (W3Schools, 2015).

Figur 4 Exempel på en array i JavaScript.

Figur 3 visar ett exempel på hur man kan skapa en array i JavaScript. Det första som görs är att deklarera en variabel, cars, och sedan tilleda de multipla värden som önskas. I det här fallet är det ett flertal bilmärken som tilldelas till variabeln cars. Den stora fördelen med arrayer är att man kan förvara multipla värden i en enda variabel istället för att skapa en variabel per värde vilket även ger möjligheten att loopa (gå igenom) variabeln för att finna en specifik entitet. Tänk dig att du har en lång lista med bilmärken och du sparar ned dessa i varsin variabel kallad cars1, cars2, cars3 etc. för varje bilmärke. Detta är inget problem men om du istället har flera hundra bilmärken och vill ha möjlighet att loopa igenom en sådan lista, då är den enda möjligheten att skapa en array (W3Schools, 2015).

Figur 5 Exempel på tilldelning av flera variabler.

Khan, et al (2014) tar bland annat upp att eftersom JavaScript är dynamiskt typat så kommer de arrayer som skapas att innehålla värden av flera typer samtidigt som en array kan innehålla värden av olika typer. Detta skiljer sig från typed arrays som istället har flera olika typer av arrayer, exempelvis Float32Array som enbart innehåller en datatyp (float).

(9)

2.6 Typed arrays

Typed arrays är ett API som används flitigt för många JavaScript applikationer, speciellt för applikationer som arbetar mycket med stora mängder data. Typed arrays erbjuder ett sätt att effektivt hantera stora mängder binär data genom att tillåta JavaScript att skapa stora arrayer med väldigt lite overhead (Matsakis, Herman & Lomov, 2014).

Grimmer, Würthinger, Wöß & Mössenböck (2014) skriver bland annat att Typed Arrays kan användas för att tillåta programmerare att komma åt internminnet genom JavaScript (vilket är omöjligt i enbart JavaScript eftersom det saknar statisk typinformation).

För att uppnå maximal flexibilitet och effektivitet så delas typed arrays in i buffers och views vilket kan förklaras på följande vis:

”A buffer (implemented by the ArrayBufferobject) is an object representing a chunk of data; it has no format to speak of, and offers no mechanism for accessing its contents. In order to access the memory contained in a buffer, you need to use a view. A view provides a context — that is, a data type, starting offset, and number of elements — that turns the data into an actual typed array” (Anon, n.d.)

Mer ingående kan man säga att ArrayBuffer är en datatyp som används för att representera en generisk, fast storleksmässig binär data buffer vilket du inte kan manipulera direkt. Du är således tvungen att skapa en typed array view (eller en DataView) vilket i sin tur representerar buffern i ett visst format, och använder sen den för att läsa och skriva innehållet i buffern (Anon, n.d.). Matsakis, Herman & Lomov, (2014) förklarar även att en array buffer helt enkelt består av en rå array av bytes utan interpretering.

Typed array views kan förklaras med att de har självförklarande namn och erbjuder vyer för alla vanliga numeriska typer såsom Int8 (8-bit signed integer), Uint16 (16-bit unsiged integer).

Type Size (byte) Description Equivalent C-type

Int8Array 1 8-bit signed integer int8_t

Uint8Array 1 8-bit unsigned integer uint8_t

Int16Array 2 16-bit signed integer int16_t

Uint16Array 2 16-bit unsigned integer uint16_t

(10)

3

Problemformulering

3.1 Problemet

Problemet är således att JavaScript, som är ett dynamiskt typat språk, har en försämrad prestanda gentemot ett statiskt typat språk (C/C++), vilket innebär att det exekverar genom att använda bitkodsinterpretering. Detta resulterar i att JavaScript exekverar väldigt mycket långsammare än kod skriven i ett statiskt typat språk såsom C eller C++ (Mherara, Hsu, Samadi & Mahlke, 2011).

Vidare skriver Mehrara & Mahlke (2011) att det redan nu finns många ansträngningar för att utveckla online spel samt spelmotorer i JavaScript. Eftersom dessa applikationer domineras av ett frekvent antal utförda loopar och funktioner så måste dessa typer av applikationer istället distribueras i ett mer statiskt typat språk (C/C++), detta på grund av att konsumenter inte accepterar alltför dåliga resultat som det innebär att ha dem implementerade i JavaScript.

Mehrara & Mahlke (2011) tar även upp att det är svårt för dynamiskt typade språk att uppnå högre prestanda eftersom typer av variabler varierar vid körning. Ahn, et al. (2014) förklarar detta med att JavaScript inte deklarerar några som helst variabeltyper. Detta tvingar kompileraren att använda generisk kod som kan hantera alla potentiella typer av kombinationer. Hackett & Guo (2012) tar i sin studie upp ett exempel där de visar att JavaScript använder var för att deklarera variabler, exempelvis var minVariabel = 1. Problematiken är att var enbart säger att en variabel deklareras, inte vilken typ av variabel det handlar om, vilket resulterar i att kompileraren måste skicka med kod för att hantera alla kombinationer av variabeltyper vilket i sin tur ger upphov till att väldigt mycket onödig data (overhead) skickas med vid varje kompilering.

Grimmer, Würthinger, Wöß, et al., (2014) tar bland annat upp att eftersom JavaScript är ett dynamiskt typat språk så saknar det statisk typinformation, access till internminne samt en fixerad minneslayout för variabler vid körning. Enligt Ahn, et al. (2014) resulterar detta i att man inte vet var någonstans i minnet som variabler hamnar vilket skiljer sig från statiskt typade språk där variabler har deklarerade variabeltyper och en fast plats i minnet.

Ett annat problem med den dynamiska typningen är skapandet av vanliga arrayer i JavaScript. Enligt Khan, et al. (2014) så kan dessa innehålla värden av olika typer, samtidigt som dessa värden inte behöver vara av samma typ, exempelvis kan en array innehålla både strängar och heltal. Detta ger samma problematik som vid deklarering av variabler i JavaScript där JIT-kompileraren måste skicka med onödig data (overhead) eftersom den inte vet vilken datatyp som existerar i arrayen.

Detta har i sin tur gett upphov till ett antal frågor som förhoppningsvis kan förklaras vid slutet av detta arbete.

 Kommer typed arrays som optimeringsstrategi för sökalgoritmer i JavaScript att sänka svarstiden?

 Kommer typed arrays vara att föredra vid krävande algoritmer?

(11)

 Hur står sig platta arrayer jämfört med vanliga 2-dimensionella arrayer i JavaScript? Tidigare studier har genomförts när det kommer till optimering av JavaScript för numeriska beräkningar (Khan, et al. 2014). Fokus för dessa har varit att mäta och jämföra testresultat för ett antal applikationer skrivna i tre varianter av JavaScript, samt om prestanda för parallell beräkning genom användandet av WebCL och OpenCL. För den här studien kommer fokus istället handla om att tillämpa statisk typinformation för sökalgoritmen A* eftersom denna algoritm är vanligt förekommande i spelutveckling (Cazenave, 2006). Studien försöker således att optimera bort användandet av vanliga JavaScript arrayer och tillämpa statiskt typade arrayer (typed arrays) vilket förhopnningsvis resulterar i att sökalgoritmen exekverar snabbare.

3.2 Hypotes

Hypotesen är att svarstiden minskar vid användandet av optimeringsstrategin typed arrays för sökalgoritmen A* i JavaScript jämfört med samma sökalgoritm fast utan användandet av en optimeringsstrategi. Denna hypotes styrks av det resultat som Khan, et al. (2014) fick fram i sitt arbete.

(12)

3.3 Metodbeskrivning

3.3.1 Experiment

Det här arbetet kommer utföras som ett experiment eftersom det anses vara den bästa metoden för att påvisa sanningshalten av den hypotes som existerar. Wohlin, et al. (2012, 16) tar bland annat upp att en av de stora fördelarna med en experimentell metod är att man får kontroll över testsituationen. Andra fördelar är att man kan genomföra statiska analyser genom metoder för hypotestestning samt möjligheter för replikering.

Khan, et al. (2014) beskriver ett experiment där de undersöker prestandan av JavaScript i ett antal olika webbläsare och plattformar. De studerade bland annat prestandan för en numerisk applikation handskriven i JavaScript, handskriven i JavaScript med typed arrays implementerat samt maskingenererad asm.js kod av applikationen och sedan jämförde de resultat från dessa mot resultatet för den numeriska applikationen skriven i C.

Det experiment som skall utföras i det här arbetet är till viss del en replikation av vad Khan,

et al. (2014) utförde i sitt arbete. Enligt Wohlin, et al. (2012, 19) handlar replikering om att

försöka upprepa ett tidigare experiment under liknande förhållanden eftersom det hjälper till med att ta reda på hur mycket förtroende det finns i resultatet av experimentet.

Khan, et al. (2014) utförde som sagt experiment med olika typer av JavaScript som de sedan mätte prestandan av i ett antal olika webbläsare (Chrome, Firefox, Internet Explorer och Safari) där de var fördelade på två stycken plattformar, en desktop med Windows 7 och en bärbar med OS X. Fördelningen såg ut som så att för plattformen desktop så testades Chrome, Firefox och Internet Explorer medan plattformen bärbar så testade man Safari, Chrome och Firefox. Detta är något som kommer replikeras även för detta experiment eftersom det ger en bred bild av hur prestandan kommer se ut för sökalgoritmen på två stycken vanligt förekommande plattformar med de vanligast förekommande webbläsarna. Khan, et al. (2014) tog som sagt upp några testfall i sitt experiment, vilka är nästintill identiska med vad som skall testas för det här arbetet.

 Handskriven JavaScriptkod utan optimeringar

 Handskriven JavaScriptkod med optimeringsstrategin platta arrayer  Handskriven JavaScriptkod med optimeringsstrategin typed arrays

I Khan, et al. (2014) skriver de även om att baslinjen är deras numeriska applikation implementerad i C, men för det här experimentet så är det mer relevant att använda handskriven JavaScriptkod utan optimeringar som baslinje och sedan jämföra resultatet av detta med de andra två testfall som skall genomföras.

För att mäta svarstid av sökalgoritmen A* så kommer någon form av räknare att implementeras. Rajamony & Elnozahy (2001) tar bland annat upp hur man implementerar en räknare i JavaScript med hjälp av funktioner i JavaScript som hämtar starttid och sparar ned den så att den finns lagrad för senare evaluering tillsammans med en sluttid som också hämtas av en funktion implementerad i JavaScript.

(13)

3.3.2 Alternativa metoder

Det finns, förutom experiment, alternativa metoder som kan vara av intresse. Enligt Wohlin,

et al. (2012, 14) är en av dessa metoder fallstudie. En fallstudie är något som används för att

undersöka en ensam entitet eller ett fenomen i sin riktiga kontext och inom en specifik tidsram. Den som utför en fallstudie samlar under denna tidsram på sig detaljerad information om ett fall för att få en mer detaljerad kunskap.

Wohlin, et al. (2012, 14) skriver även om vad som skiljer en fallstudie från ett experiment och tar då upp att experiment förhåller sig till variablerna som manipuleras medan en fallstudie väljer bland de variabler som representerar en typisk situation. Fördelar med en fallstudie gentemot experiment är således att de är lättare och planera samt att de är mer realistiska men resultat av dessa är svåra att tyda.

Utifrån ovanstående definition om fallstudie så skulle en fallstudie vara intressant sett ur ett användarperspektiv där användare skall försöka uppfatta huruvida sökalgoritmen exekverar snabbare vid användandet av optimeringar eller inte. Ett experiment kan endast ge ett tydligt svar och säga att den ena är bättre än det andra men det saknar tyvärr den realistiska synvinkeln när det kommer till vad riktiga användare uppfattar som snabbare eller långsammare, i det här fallet om svarstiden minskar vid användandet av optimeringsstrategin typed arrays eller inte.

3.3.3 Metoddiskussion

Syftet med det här arbetet är att försöka hitta vilken implementation av sökalgoritmen A* som kommer generera den minsta svarstiden i ett flertal olika webbläsare. Arbetet som sådant kommer utvärderas genom att sammanställa svarstiderna för de olika webbläsarna och för varje enskilt testfall för att se vilken implementation av A* som genererade den minsta svarstiden för de olika webbläsarna.

De potentiella metodologiska problemen med experiment som undersökningsmetod för att mäta svarstid rent praktiskt är att val av webbläsare kan spela stor roll i hur snabbt en applikation exekverar. Khan, et al. (2014) tar bland annat upp att deras applikation exekverade nästan 10x snabbare i Chrome och Firefox än vad den gjorde i Internet Explorer vilket innebär att resultatet kan vara missvisande gentemot applikationen implementerad i olika versioner.

Experimentet kommer utföras på två olika plattformar där de webbläsare som skall användas inte kommer installeras på alla plattformar. Det innebär att för plattformen stationär dator med Windows installerat så kommer enbart Chrome, Firefox och Internet Explorer att användas medan det för bärbar dator med Mac OS X är webbläsarna Chrome, Firefox och safari installerade vilket är en replikation av Khan, et al. (2014) arbete. Problemet med detta är att inte alla webbläsare testas för båda plattformarna vilket kan

(14)

3.3.4 Forskningsetik

Eftersom de tester som utförs i det här arbetet skall vara återupprepningsbara i framtiden så måste viss information såsom hårdvaruspecifikationer, webbläsare, operativsystem, testdata och resultat presenteras i arbetet. Nerurkar & Wu (1998) tar bland annat upp att om mätningar skall anses pålitliga så måste de gå att återupprepa vid ett senare tillfälle vilket styrker kravet på att viss information måste förmedlas i detta arbete.

Förutom detta kommer inga externa bibliotek att användas som skulle kunna ha en påverkan på de mätningar som skall genomföras. Eftersom inga testpersoner kommer användas i det här arbetet så är de etiska problemen med hantering av personlig information små samt att all data som skall användas i arbetet inte har några som helst anknytningar till verkligheten vilket innebär att det inte heller här förekommer några etiska problem.

För att säkerställa objektiviteten när det kommer till valet av webbläsare så kommer ett antal webbläsare att väljas ut eftersom det annars vore oetiskt att enbart välja en. Det finns förvisso etiska problem med att även välja ut ett antal webbläsare och inte välja alla som finns tillgängliga men även dessa problem är minimala.

(15)

4

Genomförande

4.1 Förstudie

För att få idéer och inspiration för den webbapplikation som skall implementeras så användes en förstudie. Flanagan (2011) har varit en stor inspirationskälla när det kommer till att förstå JavaScript och framför allt att utveckla en webbapplikation anpassad för webben. Boken ger även en stor förståelse för hur arrayer fungerar samt olika typer av arrayer vilket var användbart vid implementeringen av webbapplikationen för att hitta bästa lämpade array.

En annan inspirationskälla som har använts är Mozilla Developer Network (Anon, 2015) för att implementera typed arrays för webbapplikationen. Sidan ger väldigt bra information kring vilka typer av typed arrays som existerar samt hur implementeringen går till vilket har varit väldigt användbart eftersom det har gett idéer kring hur de skall implementeras i webbapplikationen.

När det kommer till att försöka finna idéer kring spelplanens utformning och att använda ett grafiskt gränssnitt så har Kaitila (2013) en väldigt bra artikel om hur algoritmen A* kan användas tillsammans med HTML 5 Canvas för att rita ut en spelplan. Detta sätt känns som det absolut bästa eftersom det ger möjligheten till att skapa ett tileset (bildserie) som kan användas för att bestämma hur vägar och hinder skall vara utformade.

En annan inspirationsskälla är Gustavsson (2015) som tillhandahåller en klassisk variant av sökalgoritmen A* vilket är väldigt användbart när det kommer till utvecklingen av webbapplikationen. Denna variant kan genast implementeras för det här arbetet eftersom det intressanta är att optimera denna för detta ändamål. Lyckligtvis är denna variant redan implementerad i JavaScript vilket även det kommer underlätta implementeringen för den här webbapplikationen.

4.2 Progression

Under progression kommer ett flertal steg att genomföras för att få fram den webbapplikation som skall användas för att söka svar på den hypotes som finns. Det första steget handlar om att implementera grundstrukturen av webbapplikationen i form av grafiskt gränssnitt samt se till så att sökalgoritmen fungerar. De kvarvarande stegen handlar i sin tur om att försöka optimera webbapplikationen och även implementera typed arrays.

4.2.1 Implementera grunden

Den första versionen av webbapplikationen implementeras där det i första hand handlar om att försöka skapa någon form av spelplan, ett grafiskt gränssnitt, som algoritmen skall söka

(16)

Figur 7

Visar rutinformation

Exempelvis deklarerar man att typ av ruta kan vara allt mellan 1-4, där 1 representerar vägar och 4 representerar hinder. Detta används sedan tillsammans med ett tileset, en grafisk bild av pixlar, som representerar ett flertal bildobjekt. Varje bildobjekt har ett fast antal pixlar, låt säga 16x16px, vilket medför att för varje 16x16, 32x16, 48x1 osv. så återfinns ett nytt bildobjekt. Man kan säga att pixlarna blir en form av koordinater för nästa bildobjekt vilket är väldigt användbart eftersom man då kan bestämma att varje bildobjekt alltid är 16x16 pixlar och således vet man att man kan hämta ett nytt bildobjekt för varje 16x16px, se figur 8 för en bild av ett tileset med olika bildobjekt.

Figur 8 Tileset

Figur 9 visar resultatet för den implementerade spelplanen där utkanterna är väggar som skall avgränsa spelplanen medan de gröna fälten representerar vägar som algoritmen kan gå genom. Slutligen representerar de gula fälten de hinder som har genererats fram och som algoritmen måste söka sig förbi för att nå målet.

Figur 9 Spelplan utritad i canvas

Nästa steg var att skapa någon form av gränssnitt för själva webbapplikationen i form av en kontrollpanel vilket gör det möjligt att skriva in antal iterationer som skall genomföras, skriva ut data efter utförda iterationer samt möjligheten att ändra storlek på spelplanen och

X:33;Y:5;gScore:10000;fScore:0; kind:4;tileno:0;fathx:0;fathy:0; X:33;Y:6;gScore:10000;fScore:0; kind:4;tileno:0;fathx:0;fathy:0; X:27;Y:5;gScore:10000;fScore:0; kind:4;tileno:0;fathx:0;fathy:0; X:33;Y:8;gScore:10000;fScore:0; kind:1;tileno:0;fathx:0;fathy:0; X:26;Y:6;gScore:10000;fScore:0; kind:1;tileno:0;fathx:0;fathy:0;

(17)

Figur 10 Kontrollpanel i gränssnittet.

Detta kommer underlätta inte minst vid testningen som skall genomföras eftersom man direkt vid avslutad testning får fram all relevant data där man ser om någon iteration fallerade samt tidsåtgången. Det finns även en knapp för att ladda ned en Excel-fil med all data vilket även det underlättar vid analyseringen.

Sedan är det dags att implementera en klassisk variant av sökalgoritmen A* för webbapplikationen. Figur 11 visar hur implementationen ser ut för webbapplikationen i ett första skede. Funktionen som sådan fungerar på så sätt att den anropar checkTile() 4 gånger per ruta (tile) där den undersöker grannarna till den rutan (höger, vänster, upp, ner). Figur 12 visar en illustration som bättre förklarar vilka som räknas som grannar för respektive ruta.

(18)

Checktile() är i sin tur en funktion som går igenom den tile som skickades med in som

parameter. Där undersöks bland annat om rutan är en väg eller ett hinder samtidigt som den sedan läggs i en kö för att hålla reda på vilka rutor som har blivit besökta.

Ett sista steg är att börja implementera en grundpelare, själva tidtagningen. Eftersom det intressanta i det här fallet är att veta hur lång tid sökalgoritmen A* tar för att söka sig fram till en given slutpunkt så är det ganska uppenbart att det är för den funktionen som tidtagaren skall implementeras.

Som ett första steg implementeras en variabel som skall hålla tiden, startTimeNow, i funktionen som innehåller algoritmen. Tanken med detta är att spara ned starttiden som sedan skall användas vid beräkning av den faktiska tiden. I vanliga fall används getTime() för att mäta tid men eftersom det handlar om millisekunder i det här fallet så är det mer relevant att få en mer precis tid, därav performance.now() som är säker upp till en tusendel av en millisekund.

Figur 13 Skapa starttid.

När algoritmen sen har nått sitt slut så hämtas en ny tid och sparas ned i variabeln

endTimeNow. Sedan subtraherar man endTimeNow med startTimeNow vilket resulterar i

den aktuella tidsåtgången och denna sparas ned i variabeln sumNow för senare åtkomst.

Figur 14 Skapa sluttid och subtrahera.

4.2.2 Optimering array för rutnät

Som ett andra steg i implementeringen av webbapplikationen så är det dags att optimera den array som innehåller information om spelplanen i ett försök att snabba på exekveringen samtidigt som det kommer underlätta vid implementering av typed arrays vid ett senare tillfälle. Nuvarande array (figur 15) är en 2-dimensionell array vilket skall ersättas med en enda platt array som för varje ruta lagrar 8 värden på ett förbestämt index. Figur 16 visar hur den nya arrayen har implementerats och här kan man tydligt se att för index 0 och 1 så lagras och Y-koordinater vilket innebär att man vid ett senare tillfälle kan hämta just X-koordinaten genom att hämta index 0.

(19)

Figur 16 Bild på optimerad array.

Ett exempel på hur en hämtning av X-, Y-koordinater och även kind (typ av ruta) ser ut kan ses i figur 13. Två stycken for-loopar som itererar över X- och Y-koordinaterna för att hämta alla värden i arrayen och sedan hämtas data beroende på index (+0, +1, +4 i det här fallet).

Figur 17 Hämta värden från array.

Det var till en början inte helt enkelt att byta ut den gamla 2-dimensionella arrayen mot en platt array. Bland annat uppstod problem i utformningen av den platta arrayen vilket till en början gjorde det svårt. Andra problem med den nya arrayen var att den till en början endast använde 6 element per ruta vilket motsvarar hur den gamla arrayen fungerade. Problemet med detta var att den gamla arrayen bestod av ett objekt med egenskaper (figur 15) vilket gjorde att man vid ett senare tillfälle kunde lägga till fler egenskaper till samma objekt och sedan hämta dessa, se figur 18 för hur detta fungerar.

Figur 18 Visar en gammal tilldelning.

För att lösa detta dilemma så blev lösningen att lägga till två nya index (6 & 7) som skall innehålla fathX och fathY vilket i sin tur resulterar i att de finns lagrade i arrayen redan från början och då går det att komma åt dessa genom index 6 och 7, se figur 19.

(20)

4.2.3 Optimering array för vägar

Den andra optimeringen som gjordes var på den array som håller information om de vägar som har besökts av algoritmen vid en sökning, detta eftersom den alltid skall hitta tillbaka till föräldranoden (startpunkten). Den första implementationen av arrayen var en 2-dimensionell array (figur 20) som nu optimeras genom att skapa en platt array istället.

Figur 20 Första version av HSHPush().

HSHPush() är den funktion som lägger in nya element i arrayen, den tar emot två

parametrar, x och dataVal, där x-värdet bestämmer på vilken plats i arrayen som dataVal skall bli inskickad genom push(). Den optimerade HSHPush() (figur 21) tar in ett flertal parametrar istället för objektet dataVal. Sedan skapas en form av indexering för att lagra parametrarna på specifik plats i arrayen. Antal är en parameter som skall hålla reda på hur många värden som återfinns för en specifik plats, exempelvis kan flera push göras till samma plats i arrayen, dessa läggs då efter varandra.

(21)

Den andra funktionen (figur 22) som optimerades var den funktionen som hanterar borttagning av element i arrayen, HSHPop(). Funktionen som sådan behöver även den optimeras för att hantera den nya arrayen som skapats

Figur 22 Första version av HSHPop().

De viktigaste aspekterna för den optimerade versionen var bland att se till så att den är sammanlänkad med den nya arrayen. Vad funktionen i stora drag gör är att den letar fram den kortaste vägen och tar bort den från den öppna listan och lagrar den i den stängda listan för att veta den minst kostsamma vägen tillbaka till startpunkten.

(22)

Slutligen var det bara en funktion kvar och optimera och det var HSHClear() som har till uppgift att tömma arrayen vid varje körning.

Figur 24 Första version av HSHClear().

Den optimerade HSHClear() blev något mindre men utför i princip exakt samma uppgift, att sätta arrayen till 0 innan varje ny körning. Den gör det genom att loopa igenom arrayen ett antal gånger för att tömma varje plats innan den återställer Shortest och Longest variablerna till sitt ursprungsvärde.

Figur 25 Optimerad version av HSHClear().

Det har även för denna del funnits ett antal problem där det ena var att variabeln antal vid anrop till HSHPop() kunde bli ett negativt värde, den fortsatte således att ta bort tills hela arrayen var tom (vilket tog tid). Lösningen blev att implementera en if-sats som har till uppgift att se till så att den enbart tar bort när arrayen har värden i sig.

Ett annat problem var att var antal = arr[ind] i HSHPush() till en början returnerade

undefined vilket tog ett tag att hitta en lösning på samtidigt som det ställde till problem när

det kom till tilldeningen för pos där varje pos fick värdet av gScore. Det visade sig att lösningen var enklare än vad det först verkade där lösningen gick ut på att köra HSHClear() innan första sökningen så att arrayen blev definierad till 0.

Sista problemet var att algoritmen enbart körde en gång och sedan tog det stopp eftersom den av oförklarlig anledning stannade vid första körningen varje gång. Även här var det ett mindre fel som var enkelt att åtgärda eftersom det objekt som returnerades från HSHPop() innehöll fel egenskaper gentemot de som hämtades vid ett senare tillfälle.

(23)

4.2.4 Optimering Typed arrays

Nu är det dags att implementera optimeringsstrategin typed arrays vilket innebär att byta ut de vanliga JavaScript arrayer (exempelvis var array = [];) som är implementerade i webbapplikationen. Den första arrayen som skall bytas ut är den array som innehåller rutnätet (figur 26) och den byts ut mot en Int32Array (figur 28) som representerar en array av 32-bit signerad integer. Här används även en ArrayBuffer som bestämmer hur många bytes som skall lagras. Den multipliceras med 4 i det här fallet eftersom Int32Array används.

Figur 26 Första version av array för tiles.

Den största skillnaden mot hur man i vanliga fall deklarerar en ny array är att man vid användandet av typed arrays även deklarerar den faktiska storleken på den nya arrayen eftersom detta inte går att ändra när arrayen väl är skapad.

Figur 27 Optimerad array med typed arrays.

Nästa array som skall optimera med typed arrays är den array som innehåller de vägar som algoritmen sparar undan när den söker sig fram till den givna slutpunkten. Figur 28 visar hur den nya implementationen har gått till där variabeln arrLength innehåller ett uppskattat värde av storleken på arrayen som skall skapas. Sedan deklareras en Int16Array i det här fallet för att få plats med hela storleken i arrayen. Även här används en ArrayBuffer för att bestämma antal bytes.

Figur 28 Optimerad array med typed arrays.

Att implementera typed arrays har varit förvånansvärt enkelt att implementera, det

handlade i regel bara om att byta ut den vanliga arrayen mot en array som passar ändamålet och att sedan uppskatta värdet på arrayerna som skall skapas eftersom detta inte går att ändra när arrayen är skapad.

(24)

4.2.5 Automatisering av applikation

För att snabba på mätningarna som skall genomföras så infördes ett antal funktioner som har till uppgift att underlätta mätningarna i allra största möjliga mån. Dessa kan ses i figur 29 vilket skiljer sig en aning från vad som visas i figur 10.

Figur 29 Automatiserad applikation.

Den största skillnaden är att kontrollgränssnittet för att bestämma storlek på banan togs bort eftersom banan som sådan är av samma storlek för alla mätningar vilket gjorde att den funktionen blev överflödig. Sedan har även en ny inmatningsruta lagts till (Roads) som används för att bestämma hur många sökvägar som skall genomföras per iteration. Inmatningsrutan för iteration innebär att man bestämmer hur många iterationer som skall genomföras med x antal vägar.

Ett exempel kan vara att man vill köra 100 iterationer gånger 50 vägar där syftet med att använda flera vägar är att få ett resultat där vägarna antingen är lyckade eller misslyckade, se figur 30 för hur en iteration med 10 vägar kan se ut efter körning.

Figur 30 Visar genomförd iteration med 10 vägar.

Andra förändringar är de radioknappar som har lagts till för webbläsare, versioner samt mängden av hinder (small, medium, large). Dessa används enbart för att namnge den fil som man efter utfört test kan ladda ned genom ladda ned-knappen för att på ett enkelt sätt hålla reda på vilka filer som tillhör vilket testfall.

(25)

4.3 Pilotstudie

En pilotstudie har genomförts för ett antal webbläsare för att se om webbapplikationen kan genomföra de mätningar som är relevanta för det här arbetet samtidigt som det svarar på om alla mätningar kan genomföras på de tilltänkta webbläsarna. Pilotstudien genomfördes genom att köra webbapplikation 100 iterationer per webbläsare och sedan sammanställdes all testdata i en graf. Testerna utfördes på en MacBook Pro 2.6 GHz processor med 16 GB minne.

De testfall som utfördes visade ett antal spikar (visas inte i nedanstående grafer) vilket beror på att sökalgoritmen inte har lyckats hitta någon väg på hela spelplanen som når fram till slutpunkten, detta beror på att slutpunkten har hamnat innanför ett slutet hinder. Eftersom varje slutpunkt är helt slumpad så finns ingen funktion som kollar om slutpunkten har hamnat innanför en sluten omkrets. Det är dessutom relevant att se hur lång tid det tar för sökalgoritmen att söka av hela spelplanen innan den kastar ur sig ett felmeddelande. Figur 31 visar hur det ser ut när algoritmen har sökt igenom hela spelplanen utan att hitta en väg till slutpunkten som är lokaliserad innanför ett slutet hinder.

(26)

4.3.1 Utan optimeringsstrategi

Det första pilottestet utfördes med webbapplikationen utan optimeringsstrategi vilket gav följande resultat för de olika webbläsarna (figur 32) där Safari visade sig vara snabbare än sina konkurrenter Chrome och Firefox. Resultatet som sådant skall ändå tas med en nypa salt eftersom det endast utfördes 100 iteration per webbläsare vilket anses som lite och kan vid exempelvis 5000 iterationer ge helt andra testresultat.

Pilottestet har dock påvisat att det går att mäta exekveringstiden för webbapplikationen och dess algoritm för de nämnda webbläsarna vilket var huvudsyftet med pilottestet. Det gav förvånansvärt jämna resultat överlag förutom ett antal spikar (syns inte i diagrammet nedanför) där algoritmen inte fann slutpunkten och sökte över hela spelplanen utan att lyckas.

Figur 32 Medelvärde för webbläsare.

Hur det kommer sig att Safari presterar bättre än sina konkurrenter är bara något man kan spekulera i men eftersom testerna utfördes på en MacBook Pro så är det inte helt omöjligt att anta att Safari är den webbläsare som är mest anpassad för vald datortyp (den är standard). Det vore därför intressant att köra samma testfall på en vanlig PC för att se om de testfallen avviker från dessa och i vilken utsträckning.

4.3.2 Typed arrays

Det utfördes även ett pilottest för optimeringsstrategin typed arrays för att se om den hade någon påverkan på mätresultatet jämfört med utan optimeringsstrategi. Resultatet kan ses i figur 33 och det visade sig att typed arrays presterade något bättre medeltid jämfört med vanliga JavaScript arrayer. Safari var även denna gången något bättre än sina konkurrenter medan det blev en tydligare skillnad mellan Chrome och Firefox jämfört med utan optimeringen typed arrays. Skillnaden beror med stor sannolikhet på att det fanns fler misslyckade iterationer i testfallet för Firefox än för Chrome vilket resulterar i ett högre medelvärde.

(27)

Figur 33 Medelvärde för typed arrays.

Slutligen kan följande graf i figur 33 visa en jämförelse sida vid sida där det klart och tydligt kan påvisas en prestandaskillnad mellan användandet av typed arrays och vanliga JavaScript arrayer vilket stärker att hypotesen stämmer redan nu.

(28)

5

Utvärdering

Här nedanför presenteras samt analyseras alla de mätresultat som framkommit efter utförda mätningar. Utvärderingen som sådan fokuserar i stora drag på jämförelsen mellan de olika plattformarna, versioner av applikationen i förhållande till webbläsare samt de olika varianterna av banan som användes under mätningen.

5.1 Plattformar, hårdvaruspecifikation och parametrar för testning

För de här mätningarna så har två stycken plattformar används med olika operativsystem och hårdvaruspecifikationer, flertal webbläsare för varje plattform, två stycken statiska slumparrayer som innehåller data för att rita ut hinder och vägar, en fast storlek för banstorleken samt 3 olika svårighetsgrader för antalet hinder (small, medium, large). Nedan följer en hårdvaruspecifikation för de båda plattformarna som användes under testningen.

Plattform MacBook Pro HP Laptop

Operativsystem OS X Yosemite (10.10.3) Windows 8.1 64-bit Processor 2.6 GHz Intel Core i5 2.4 GHz Intel Core i7

Minne 16 GB 1600 MHz DDR3 8 GB 1600 MHz DDR3

Grafik Intel Iris 1536 MB Geforce GT 630M

Lagring Flashlagring 256 GB Samsung SSD 840 256 GB

Figur 35 Tabell för hårdvaruspecifikation.

Nedan följer en tabell för vilka webbläsare som testades för vilken plattform.

Plattform Chrome Firefox Safari

MacBook Pro Ja Ja Ja

HP Laptop Ja Ja Nej

Figur 36 Tabell för vilka webbläsare som testades på vilken plattform.

De två stycken slumparrayer som användes återfinns i appendix E & F för att ge möjligheten till replikerin. Noterbart för dessa är att alla talen är slumpade genom en slumpgenerator men att de nu lagras i varsin array där de får en statisk ordning vilket tillåter replikering i framtiden. Banstorleken (tilestorlek) bestämdes till 100x100 tiles där 1 tile är 16px vilket resulterar i en 1600x1600px stor bana. Denna storlek förändrades inte under testningen. Slutligen användes tre stycken svårighetsgrader när det kommer till antalet hinder för att skapa tre stycken olika bantyper som har till uppgift att sätta applikationen på prov. Nedan följer en tabell för att se antalet hinder som användes för den specifika svårighetsgraden.

(29)

Svårighetsgrad Lätt (Small) Medel (Medium) Svår (Large)

Antal hinder 300 800 1300

Figur 37 Visar antal hinder per svårighetsgrad.

Figur 38 visar en illustration över de olika svårighetsgraderna som finns för att på så sätt skapa en lättare överblick för att visa hur antalet hinder ser ut på den verkliga spelplanen.

Figur 38 Visar illustration med olika svårighetsgrad.

Mätningarna som sådana genomfördes för 100 iterationer med 50 vägar vardera (100*50) för att få en lagom mängd vägar som antingen är lyckade eller misslyckade per svårighetsgrad och testfall.

Följande testfall har valts ut då de är av mest intresse för det här examensarbetet för att se om någon optimeringsstrategi kan konkurrera med den referensmätning (baseline) som skapas, se figur 39 för alla testfall.

Testfall Version av applikation

JavaScript utan optimering (baseline) V2

JavaScript med optimerat rutnät V3

JavaScript med optimerad sökalgoritm V4

JavaScript med typed arrays för sökalgoritm V7

(30)

5.2 Resultat

Nedanför presenteras resultaten för de mätningar som har genomförts under testningen. För varje underrubrik visar tre grafer för att visa resultaten för antalet hinder (small, medium, large). Sedan, för att skapa en lättare överblick över resultaten, så skapas en graf där medelvärdet för 50 vägar och 100 iterationer jämförs för varje svårighetsgrad och version. Noterbart är att hädanefter skrivs följande: Chrome Mac, Firefox Mac, Safari Mac samt Chrome PC, Firefox PC för att särskilja webbläsare/plattform.

5.2.1 Referensmätning (V2)

Här återfinns resultatet för den referensmätning (baseline) som skall användas som referens när det kommer till att avgöra huruvida de valda optimeringsstrategierna uppfyller målen med att förbättra sökalgoritmens svarstid. Nedanför listas tre stycken grafer, en för varje svårighetsgrad (small, medium, large) för alla plattformar och webbläsare (Chrome Mac, Firefox Mac, Safari Mac, Chrome PC, Firefox PC).

Figur 40 påvisar medelvärdet för svarstiden för alla webbläsare och plattformar för version 2 av webbapplikationen och med svårighetsgrad lätt. Varje linje representerar en webbläsare och för den här och nästkommande två grafer (figur 41-42) är lägre tid att föredra.

Resultatet som sådant påvisar ett mätresultat som är relativt utspritt mellan webbläsare och plattform. Bland annat kan man urskilja att webbläsaren Firefox ligger i toppen när det kommer till svarstid för båda plattformarna (Mac och PC). Speciellt urskiljer sig Firefox för plattformen Mac där denna ligger relativt högt vid de upphöjningar som visar i grafen. För de webbläsare som hade den minsta svarstiden så kan man se både Chrome och Safari för plattformen Mac där dessa två tenderar att växla sinsemellan, bland annat påvisar Safari Mac en allt jämnare linje än Chrome Mac men att den sistnämnda verkar ha en något mindre svarstid rent generellt.

Figur 40 Visar medelvärde med standardavvikelse för litet antal hinder.

Figur 41 visar förhållandevis samma ordning vad gäller webbläsare/plattform som figur 40 även när svårighetsgraden har ökat. Även här har Chrome Mac en väldigt jämn svarstid för både lyckade/misslyckade vägar vilket är klart bäst av samtliga webbläsare oberoende av plattform men resultaten som sådana är mer samlade här än vad de var för liten mängd hinder (figur 40). Tidsåtgången har ökat från att ligga mellan 1-10 millisekunder (figur 40) till att ligga mellan 1-20 millisekunder i figur 41 vilket var ett klart väntat resultat eftersom

(31)

Firefox Mac genom att prestera klart sämst och påvisa ett resultat som är snäppet högre än för de andra webbläsarna vilket kan ses tydligt i topparna som återfinns i grafen.

Figur 41 Visar medelvärde med standardavvikelse för medel antal hinder.

Figur 42 påvisar ett liknande resultat som i figur 41 med ett flertal toppar. Det skiljer inte mycket mellan webbläsarna och ordningen är ungefär densamma som i de övre graferna där Firefox Mac/PC återfinns i toppen (sämst prestanda) jämfört med Chrome Mac och Safari Mac som ännu en gång presterar väldigt bra rent generellt. Även här ligger svarstiden mellan 1-20 millisekunder och här ses även att topparna är väldigt höga.

Figur 42 Visar medelvärde med standardavvikelse för stort antal hinder.

För att skapa en ännu enklare överblick över resultaten så återfinns det i figur 43 en graf där medelvärdet för alla vägar har sammanställts för varje webbläsare/plattform vilket har gett upphov till den graf som ses. Noterbart är att grafer för högre svårighetsgrader (medel, svår)

(32)

Figur 43 Medelvärde med standardavvikelse för liten mängd hinder.

5.2.2 Optimering array för rutnät (V3)

När det kommer till optimering av array för rutnät så gav det ett resultat som kan ses i följande grafer här nedanför. Rent generellt så verkar resultaten visa att alla webbläsare oavsett plattform var väldigt likartade och att det egentligen är vid topparna som man kan utröna en skillnad.

Följande figur (44) visar framför allt att svarstiden har ökat väldigt mycket i förhållande till hur föregående grafer (figur 40-42) såg ut. Här hamnar svarstiden mellan 1-2500 millisekunder för de högsta topparna vilket är klart mer än innan (1-20 millisekunder). Nu är dock grafen inte lika inzoomad som innan vilket kan förklara varför linjerna ser ut att gå in i varandra men bortsett från det så ser det onekligen jämnt ut oavsett webbläsare och plattform. Det är som sagt enbart vid topparna som man kan se att det skiljer ett antal millisekunder mellan webbläsarna samtidigt som standardavvikelsen är väldigt hög även för dessa.

(33)

För figur 44 och 45 så ser mätresultaten väldigt likartade ut som för resultaten i figur 43 där det är svårt att avgöra vilken webbläsare som presterat bäst. Däremot verkar standardavvikelsen, i alla fall för topparna, visa att det är otroligt jämnt och att nästa mätpunkt mycket väl kan hamna innanför samma spann oavsett webbläsare och plattform. Man kan även utröna att Firefox PC verkar prestera klart bättre nu än vad den gjorde vid föregående version (figur 40-43). Som nämnts innan så är svarstiden väldigt mycket högre nu och det blir som sagt väldigt tydligt vid topparna (misslyckade vägar).

Figur 45 Medelvärde med standardavvikelse för medel mängd hinder.

Figur 46 visar även ett något udda resultat gentemot figur 44-45 där Chrome Mac för vägarna 4-10 ligger relativt högt jämfört med de andra webbläsarna. Hur det kommer sig är något oklart vid det här laget och kan ha flera olika anledningar där den mest troliga är tillfälligheter och att webbläsaren stött på något som tog längre tid än väntat.

(34)
(35)

5.2.3 Optimering array för algoritm (V4)

När det kommer till resultatet för optimering av den array som används av sökalgoritmen så kan man se att den ligger väldigt stabilt vid vägar som är lyckade medan den drar ifrån en aning vid vägar som räknas som misslyckade vilket även standardavvikelsen skvallrar om då den ligger väldigt högt på sina ställen. Det är en mer klar spridning mellan webbläsarna för denna optimering jämfört med hur det såg ut i förra optimeringen (figur 44-46). Man kan även se att svarstiden är väsentligt mycket lägre nu än vad den var för förra optimeringen där vi nu landar på runt 1-25 millisekunder.

Figur 48 visar även att Safari Mac är den webbläsare som presterat klart bäst (lägre millisekunder är bättre) och hamnar strax under Chrome Mac och det är i särklass dessa två webbläsare och plattform som presterat klart bäst så här långt. Topparna är någorlunda jämna vilket innebär att alla webbläsare har ungefär likvärdiga svarstider för dessa samt att standardavvikelsen vittnar om att det är väldigt jämnt. Man ser även att Firefox PC toppar något vid lyckade vägar (röd linje) men att den sedan blir en i mängden vid topparna.

Figur 48 Visar medelvärde och standardavvikelse för liten mängd hinder.

Figur 49 och 50 visar liknande resultat som för figur 48 där Safari Mac verkar prestera något bättre än sina konkurrenter. Man ser även att topparna har blivit fler vid en högre svårighetsgrad men att svarstiden fortfarande ligger innanför 1-25 millisekunder både för medel och svår svårighetsgrad.

(36)

Figur 50 visar även en större spridning mellan webbläsarna där det är en tydligare skillnad dem sinsemellan. Fortfarande presterar Safari och Chrome för plattformen Mac betydligt bättre än sina konkurrenter och att deras standardavvikelse även den skvallrar om att de är väldigt jämna. Svarstiden är också den något lägre, runt 1-15 millisekunder istället för 1-25 millisekunder som för figur 48-49 förutom något enstaka fall där Firefox Mac drar iväg med ett antal toppar över 15 millisekunder.

Figur 50 Visar medelvärde med standardavvikelse för medel antal hinder.

Figur 51 påvisar det som nämndes här ovan med att Safari Mac ligger väldigt bra till prestandamässigt samtidigt som dess följeslagare Chrome Mac även den påvisar fina resultat. Samtidigt är bådas standardavvikelse relativt likvärdiga vilket innebär att nästa mätpunkt har en teoretisk möjlighet att hamna inom ramen för dessa två. Standardavvikelsen är något hög för Chrome PC och Firefox PC än vad den är för de andra webbläsarna vilket gör att den når upp till standardavvikelsen för Firefox PC. Även här ser vi att Firefox Mac är sin vana trogen och förhåller sig något högre än de andra. Fler grafer återfinns i appendix G för de andra svårighetsgraderna.

(37)

5.2.4 Optimering Typed Arrays (V7)

Det sista testfallet som gjordes var den optimering som tillämpar typed arrays för algoritmens array. Resultaten som helhet är väldigt lika de som påvisats för de andra testfallen där man kan se en någorlunda skillnad mellan webbläsarna oavsett plattform men också att svarstiden ligger mellan 1-10 millisekunder förutom för Firefox Mac som fortfarande har några rejäla toppar. Det som är mest intressant för den här optimeringen och utslaget av resultaten är att den verkar ligga på ungefär samma nivå som referensmätningen vilket helt klart är väldigt intressant.

Nedanstående graf (figur 52) visar en klar fördelning mellan de olika webbläsarna där Safari och Chrome för plattformen Mac fortfarande presterar väldigt bra gentemot de andra webbläsarna. Svarstiderna är även dem väldigt bra förutom för Firefox Mac som av oförklarliga skäl är något högre. I mitten av grafen återfinns Chrome och Firefox PC där deras linjer är snudd på likartade, endast minimala skillnader.

Figur 52 Visar medelvärde med standardavvikelse för liten mängd hinder.

Figur 53-54 har ett något jämnare resultat men det går fortfarande att utröna skillnader mellan webbläsarna. Standardavvikelsen är förhållandevis låg oavsett webbläsare och vad man kan se mer är att Safari och Chrome för plattformen Mac presterar något bättre medan Firefox Mac drar upp svarstiden något vid topparna.

(38)

För figur 54 så ser vi även att det har blivit en tydligare skillnad mellan webbläsarna, framför allt för Firefox Mac som drar ifrån ytterligare vid de tillfällen där algoritmen inte har hittat slutpunkten (topparna). Annars så är det ett mer samlat resultat där webbläsarna ligger väldigt tätt ihop.

Figur 54 Visar medelvärde med standardavvikelse för medel mängd hinder.

Den förenklade grafen (figur 55) visar att Chrome Mac och Safari Mac är väldigt likartade även för detta testfall samt att Firefox Mac ligger klart sämst till prestandamässigt ännu en gång. Standardavvikelsen för dessa två är relativt jämn. Chrome PC och Firefox PC förhåller sig till varandra som vi även har sett tidigare och standardavvikelsen är även här jämn.

(39)

5.3 Analys

Analysen nedan påvisar medelvärdet för alla webbläsare/plattform och för alla versioner med de olika svårighetsgraderna vilket har renderat i tre stycken övergripande grafer (en per svårighetsgrad). Figur 56 visar att för testfallet optimerad rutnätsarray (V3) så ligger resultatet för denna en bra bit över de andra testfallen vilket har resulterat i att det är väldigt svårt att få en bra överblick för hur de andra testfallen presterade. På grund av att detta testfall ligger så pass långt efter referensmätningen (V2) så kommer detta testfall hädanefter att uteslutas ur graferna för att istället ge plats åt de andra testfallen för att skapa en bättre bild över deras mätresultat.

Figur 56 Visar medelvärde för alla versioner med liten mängd hinder.

Varför testfallet med optimerat rutnät (V3) gav ett sämre resultat jämfört med de andra testfallen kan bero på ett flertal anledningar där den mest troliga är att utformningen av den platta arrayen inte är optimal. Med stor sannolikhet skulle ett annat designval för denna array ge ett helt annat resultat än vad som kan ses här. Den egentliga orsaken till varför den presterar sämre går inte att fastställa med det här arbetet utan får istället anses vara ett framtida arbete.

Nedanstående graf (figur 57) visar tre testfall (V2, V3 och V7) med litet antal hinder och här kan man se att det är förhållandevis jämnt, endast något högre svarstid för version 4 (optimerad algoritm-array) än vad det är för referensmätningen (V2) och optimering med typed arrays (V7). Om man jämför V2 med V7 så ser man att skillnaden dem emellan är nästintill obefintlig men att V2 påvisar något bättre resultat för liten mängd hinder.

(40)

förbättring gentemot den platta arrayen (V4). Dessvärre så blev förbättring enbart likvärdig med referensmätningen och hur det kommer sig att just denna optimering presterade bäst utifrån de optimeringar som har mäts beror med stor sannolikhet på den statiska utformning som det innebär att använda typed arrays. Även det faktum att arrayen hela tiden har en fast storlek vid exekvering kan ha en avgörande roll till varför denna optimering presterade så bra gentemot de andra optimeringarna.

Figur 57 Visar medelvärde med standardavvikelse för V2, v4, V7 med liten

mängd hinder.

För figur 58 så ses ett likvärdigt resultat jämfört med figur 57. Även här har version V4 något högre svarstid än vad V2 och V7 vilket med stor sannolikt beror på designvalet när det kommer till den platta array som används. Det som egentligen skiljer denna graf jämfört med grafen i figur 57 är att optimeringen med typed arrays (V7) påvisar ett resultat som är snäppet bättre än referensmätningen (V2) även om denna är minimal och snudd på obefintlig. Hur det kommer sig att denna förbättring kan ses när svårighetsgraden har ökat är nog mer en tillfällighet än att optimeringen fungerar bättre när algoritmen sätts på prov.

(41)

Den sista grafen (figur 59) visar sammanställningen med den högsta svårighetsgraden. Detta mätresultat är även det väldigt likt det som påvisas i figur 57-58. Här kan man dock se att svarstiden är lägre än vad som visas i figur 58 och det är egentligen V4 som har presterat bättre jämfört med en lättare svårighetsgrad. Fortfarande ligger detta testfall något högre än vad det gör för V2 och V7. Man kan även se att V7 även denna gång har presterat något bättre än V2 och anledningen till detta går att diskutera. Med stor sannolikhet är det en tillfällighet men eftersom samma resultat påvisades även för svårighetsgraden medel så finns det en liten chans att optimeringen med typed arrays fungerar bättre än den ooptimerade vid högre belastning av algoritmen.

Figur 59 Visar medelvärde och standardavvikelse för v2, v4, v7 med stor mängd

hinder.

Resultaten visade också att det fanns skillnader mellan alla webbläsare och de plattformar som de testades på. Bland annat så ser man i figur 60 en tydlig uppdelning mellan webbläsarna där Safari och Chrome på plattformen Mac presterat klart bäst medan Firefox på samma plattform vid flera tillfällen presterat sämst av alla genom att ha högst svarstid. Det visade sig även att webbläsarna Chrome och Firefox för plattformen PC var tämligen förankrade i mitten av grafen.

References

Outline

Related documents

Vi har utfört en översiktlig granskning av delårsrapporten för Micro Systemation AB (publ) för perioden 1 januari till 30 juni 2009. Det är styrelsen och verkställande direktören

Lokal guide möter gruppen på flygplatsen och följer med till Radisson BLU Hotell som ligger vid populära Victoria & Alfred Waterfront (ungefär 25 minuter att köra).. Utsikt mot

I beslutet om storleken på den ordinarie utdelningen som föreslås till årsstämman 2018 har Styrelsen beaktat kassaflödet från verksamheten, finansiell ställning,

I beslutet om storleken på den ordinarie utdelningen som föreslås till årsstämman 2017 har Styrelsen beaktat kassaflödet från verksamheten, finansiell ställning,

Resultat per aktie justerat för utestående optionsrätter Resultat efter finansnetto plus finansiella kostnader Periodens resultat dividerat med medelantalet utestående aktier

Orderingången ökade med 15 procent (32 procent på jämförbar basis) till 2 202 miljoner dollar, den högsta nivån på senare år, trots full påverkan från avyttringen av

360 LARSSON Frida Gällivare EJ START. 362 OLAUSSON Anna Gällivare

● Klubben ska öka sina intäkter på sikt för att möta efterfrågan från en växande ungdoms-