Archive for juli, 2012

Profilering med python

juli 20, 2012

För att ta reda på vad som tar tid i ett program brukar man säga att man profilerar programmet. Detta är inte mycket mer än ett fint ord för att på ett standardiserat sätt att ta tid på en process och analysera var tid spenderas. Profilering är ett fantastiskt verktyg ifall man vet att man har problem med att någon operation tar mer tid än den bör. Utan profilering kan man endast göra intelligenta gissningar och försöka uppskatta huruvida en förändring av programmet har gjort någon nytta och snabbat upp den långsamma sektorn.

I python ingår standardbiblioteket cProfile för detta ändamål. Biblioteket/modulen är relativt enkelt att använda och ger väldigt tydliga resultat.

Mitt pyparallax-projekt tyckte jag ibland var lite segare vid utritning än önskvärt och efter lite studier lyckades jag skapa ett enkelt skript för att profilera modulen:

import pygame
import parallax
import cProfile # import profiler module 
# init pygame
pygame.init()
screen = pygame.display.set_mode((640, 480), pygame.DOUBLEBUF)
# init parallax
surface ps = parallax.ParallaxSurface()
ps.add('../demo/p2.png', 10)
ps.add('../demo/p1.png', 10)
# create a profiler object
p = cProfile.Profile()
# run ps.draw via the profiling object
for i in range(1000):
  p.runcall(ps.draw, screen)
# create and print stats p.create_stats() p.print_stats()

I korthet

  • importeras modulen för profilering
  • normal initiering genomförs
  • profileringsobjektet p skapas
  • p.run_call() anropas med ps.draw angiven som funktion att köra
  • profilerings information skrivs ut

detta resulterade i

  ncalls  tottime  percall  cumtime  percall filename:lineno(function)
  1000    0.122    0.000   36.688    0.037 parallax.py:50(draw)
  4000   36.547    0.009   36.547    0.009 {method 'blit' of 'pygame.Surface' objects}
  1000    0.003    0.000    0.003    0.000 {method 'disable' of '_lsprof.Profiler' objects}
  1000    0.003    0.000    0.003    0.000 {method 'get_height' of 'pygame.Surface' objects}
  3000    0.015    0.000    0.015    0.000 {method 'get_width' of 'pygame.Surface' objects}

Som man ser i tabellen ovan spenderas klart mest tid i blit-operationen. Efter att läst på lite grann får jag reda på att ifall man använder färg-mappad-transparens (color keyed) dvs, man låter en särskild färg representera transparens, måste varje pixel utvärderas för sig. Snabbt inser jag att man enkelt kan ta bort detta från det bakersta lagret (som alltid måste vara heltäckande). Kod för detta sätts in i parallax-modulen

        if len(self.levels) > 0:
            image.set_colorkey((0xff, 0x00, 0xea))

dvs. aktivera endast färgmappad transparens ifall detta inte är det första (bakersta) lagret.

Vid körning av profilering-skriptet fås nu


ncalls  tottime  percall  cumtime  percall filename:lineno(function)
  1000    0.105    0.000   15.414    0.015 parallax.py:50(draw)
  4000   15.293    0.004   15.293    0.004 {method 'blit' of 'pygame.Surface' objects}
  1000    0.003    0.000    0.003    0.000 {method 'disable' of '_lsprof.Profiler' objects}
  1000    0.003    0.000    0.003    0.000 {method 'get_height' of 'pygame.Surface' objects}
  3000    0.013    0.000    0.013    0.000 {method 'get_width' of 'pygame.Surface' objects}

cumtime har nu halverats vilket är gott nog åt mig. Ytterligare besparingar kan göras genom att buffra olika lager av bakgrunden och endast uppdatera delarna ifall någon av underlagren har uppdaterats. Detta kommer dock öka komplexiteten markant och är i dagsläget inte motiverat.

Annonser

Semestern blir inte av…

juli 13, 2012

…eftersom tekniskt sett är jag arbetslös. Om en månad börjar jag på Lasermax Roll Systems och idag var sista dagen på Nibe.

Sista veckan har varit stressig och jag hann inte med allt jag hade tänkt, dokumentation har skrivits, fixar av kod jag inte varit nöjd med har lagts in och utöver sådant har ett par panikärenden kommit in och tagit mer tid än jag velat.

Tiden på Nibe har varit lärorik och jag har träffat många roliga människor, man kan säga att arbetsuppgifterna har varit spännande men det har varit kollegorna som förgyllt dagarna.

Jag har fått jobba på många olika nivåer, bitvis hanterat lågnivå programmering och drivrutiner, bitvis skrivit mer eller mindre komplexa datatyper. Vissa dagar har jag knappt suttit vid mitt skrivbord utan sprungit i fabriken och försökt förstå vad som gör att det sprutar vatten okontrollerat ur samtliga maskiner, andra dagar har jag fått sitta och modifiera kretskort för att kunna testa nya kretsar. Vi i ELK-gruppen har haft relativt god sammanhållning och har haft ett par roliga aktiviteter utanför jobbet, bland annat brädspel och kanot-paddling.

Lasermax Roll Systems har jag väldigt dålig koll på men jag ser fram emot att ta reda på hur de är. Jag är bekant med några av mina blivande kollegor och de verkar roliga och bra att ha att göra med så jag är säker på att det ska gå bra.

Tack till folket på Nibe för att ni gjort min tid på företaget till det den varit, nu mot nya äventyr!

Raspberry Pi har anlänt

juli 9, 2012

I fredags var den äntligen framme. Dess resa var strapatsrik och vid minst ett tillfälle föll den offer för odöda piraters ogärningar. Min alldeles egna Raspberry Pi kommer dock ligga i dvala tills semestern är över men dess potential strålar ut från den lilla formfaktorn.

Raspberry Pi är liten jämfört med en T-shirt

Raspberry Pi är liten jämfört med en T-shirt

För er som inte känner till den här nätta minidatorn är det viktigaste att veta att dess huvudändamål är att agera som utbildningsplattform åt skolungdomar med intresse för datorer. Tanken är att den skall vara enkel att bygga lättare projekt för, tillräckligt kraftfull för att det skall vara roligt och så pass billig att i princip alla ska ha råd med en.

Processorn på det lilla kretskortet är en 700 MHz ARM med inbyggd GPU med stöd för HD-video och stödjer OpenGL-ES. Tillsammans med de 256 MB RAM som paketet innehåller bildas en i teorin rätt kapabel helhet som ger stora möjligheter för hemma-trixare, men jag ska inte lova något innan jag provat den själv.

Det som behövs för att göra den funktionsduglig är en HDMI- eller kompositvideo-kabel för att koppla in den till en TV/skärm, ett SD-minneskort som lagringsmedia och en strömsladd. Samtliga komponenter kan man lätt få tag på i vilken hemelektronikbutik som helst.

Jag har ett par små projekt planerat för denna under hösten, vi får se hur mycket jag hinner i och med att mitt nya jobb säkert kommer uppta mycket tid och lämna en begränsad vilja till att hacka på egna projekt på fritiden