1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
<?xml version="1.0" encoding="utf-8"?>
<chapter>
<title>Guía rápida para optimizar programas de GNOME</title>
<para>Esta é unha breve introdución á optimización, dos cómos tanto dos porqués. Déixanse para posteriores artigos os detalles de ferramentas e técnicas individuais pero fornécese unha colección de suxestións e trucos.</para>
<sect1 id="optimization-intro-TBL-what-are-we-optimizing">
<title>Que se está optimizando?</title>
<para>Ao optimizar GNOME o primeiro que hai que lembrar é isto: non se está tentando mellorar o programa, estase tentando mellorando facer que as persoas usen o equipo máis felices.</para>
<para>Programas mellores fan á xente máis feliz pero existen algunhas mellores que faranos máis felices que outras: tempo de resposta, tempo de inicio, facilidade para acceder a ordes e que o equipo non teña que usar a memoria de intercambio cando máis de dous programas estean abertos.</para>
<para>A optimización tradicional contempla conceptos como o uso de CPI, o tamaño do código, o número de pulsacións do reato e o uso de memoria de programa. Elixiuse esta segunda lista para correlar como a primeira, porén existe unha diferenza importante. Á persoa que usa GNOME non lle importa a segunda lista, pero sí a primeira. Ao optimizar os programas de GNOME reducirase o uso de CPU, o uso de memoria e todo aquelo, pero son conceptos para o fin, non o obxectivo final. Optimízase para as persoas.</para>
</sect1>
<sect1 id="optimization-intro-TBL-doing-optimization">
<title>Realizar a optimización</title>
<para>Na sección anterior omitiuse un calificador importante: optimizar algo debe ser medíbel. Non se pode medir a felicidade. Porén pódese medir o tempo de inicio dun programa para saber se se mellorou. A felicidade do usuario aumentará pois.</para>
<para>A optimización é un proceso de medida, refinamento e remedida. O primeiro que debe facer é atopar unha forma de medir o que está optimizando. Idealmente a medida é un simple número, por exemplo: o tempo que se tarda en realiar unha tarefa. ESta é a súa proba, é a única forma de saber se está ganando ou perdendo. Existe unha gran diferenza entre un programa que <emphasis>deería</emphasis> ser rápido e un programa que <emphasis>é</emphasis> rápido.</para>
<para>Unha vez que ten unha proba de rendemento básica debe atopar por que o seu código non o está facendo tan ben como debería. É tentado facelo inspeccionando: simplemente mirar o código e tratar de atopar algo que parece que precisa unha mellora. Estará perdendo o tempo, usar un perfilador para obter unha lista detallada do que o seu programa está facendo é, realmente, a única forma de estar seguro.</para>
<para>Xeralmente o problema está illado en pequenas partes do código. Elixa a peor parte e concéntrese nesa primeiro. Unha vez que o teña feito, volva ao perfilador e repita o proceso. Segundo proceda, as melloras obtidas en cada paso faranse cada vez máis pequenas, nalgún punto terá que decidir que os resultados son suficientes. Se os seus esforzos só están obtendo un 10% de melloras entón fai tempo que pasou o punto en que debería ter parado.</para>
<para>
Don't forget the big picture. For example, rather than just trying to speed up a piece of code, ask yourself if it needs to be run at all. Could it be combined with another piece of code? Can the results of previous calculations be saved and reused? It won't even need to be optimized if it is in a place where the user is never going to notice it. Worse still, the code may already be optimized and is doing the heavy calculations now to avoid doing them later. Code does not run in isolation and neither does the optimization process.
</para>
</sect1>
<sect1 id="optimization-intro-TBL-hints">
<title>Suxestións</title>
<itemizedlist>
<title>O fundamental</title>
<listitem>
<para>Volva a executar a súa proba de rendemento despois de cada cambio que realice sobre o código e manteña un rexistro de todo o que cambia e de como afecta ao rendemento. Isto permítelle desfacer erros e tamén axúdalle a non repetilos.</para>
</listitem>
<listitem>
<para>Asegúrse de que o seu código é correcto e está libre de erros antes de optimizalo. Comprobe que permanece correcto e libre de erros desois de telo optimizado.</para>
</listitem>
<listitem>
<para>Optimizar ao nivel máis alto antes de optimizar os detalles.</para>
</listitem>
<listitem>
<para>Use o algoritmo correcto. O clásico exemplo de libro de texto é usar ordenación rápida no lugar de ordenación por burbulla. Existen moitos outros, algúns aforran memoria, alguns aforran CPU. Tamén debe ver que atallos de teclado pode crear: pode facelo máis rápido que unha ordenación rápida se está preparado para tomar certos compromisos.</para>
</listitem>
<listitem>
<para>A optimización é intercambio. Obter resultados mellora os cálculos pero aumenta a memoria en uso. Gardar datos ao disco aforra memoria pero custa tempo ao cargalos de novo desde o disco.</para>
</listitem>
<listitem>
<para>Asegúrese de elixir certa variedade de entradas que optimizar. SE non o fai é doado que remate cun trozo de código coidadosamente optimizado par aun campo e non para outros.</para>
</listitem>
<listitem>
<para>Evite as operacións caras: múltiples lecturas de disco pequenas. Use un montón de memoria para que o área de intercambio («swap») fágase innecesario. Evite calquera cousa que escriba ou lea innecesariamente do disco. A rede tamén é lenta. Evite tamén operacións gráficas que precisan unha resposta do servidor X.</para>
</listitem>
</itemizedlist>
<itemizedlist>
<title>Trampas para os imprudentes</title>
<listitem>
<para>Estea atento aos efectos colaterais. Xeralmente son interaccións estranas entre diferentes seccións do código, unha extensión dunha parte pode retardar outra.</para>
</listitem>
<listitem>
<para>Ao cronometrar o tempo do código, incluso nun sistema parado, os eventos fora do programa engaden ruido aos resultados de tempo. Faga unha medida sobre múltiples execucións. Se o código é moi pequeno a resolución do tempo tamén é un problema. Neste caso mida o tempo que o equipo tarda en executar o código 100 ou 1000 veces. Se os tempos que está obtendo son algo superiores a uns poucos segundos todo debería estar correcto.</para>
</listitem>
<listitem>
<para>É moi doado perferse co perfilador. Existen historias de programadores optimizando o búcle de inactividade porque é onde se perdía todo o seu tempo. Non optimice código do que o usuario non se preocupe.</para>
</listitem>
<listitem>
<para>Lembre os resultados do servidor X. O uso de memoria do seu programa non inclúe os pixmaps almacenados nos procesos do servidor X, pero aínda seguen usando memoria. Use xrestop para ver os recursos que está usando o seu programa.</para>
</listitem>
</itemizedlist>
<itemizedlist>
<title>Consellos de baixo nivel</title>
<listitem>
<para>Ao optimizar o uso de memoria considere a diferenza entre o uso de pico e o uso medio de memoria. Algunha memoria sempre está reservada, isto xeralmente é malo. Algunha está temporalmente reservada, isto pode ser aceptábel. Ferramentas como massif usan o concepto de espazo-tempo, o produto da memoria usada e o tempo durante o que estivo reservada.</para>
</listitem>
<listitem>
<para>Controle o tempo de trozos de código simplificados que só fan cousas esenciais, isto fornece un límite absoluto inferior no tempo que usará o código. Por exemplo, ao optimizar un búcle, controle o tempo do búcle baleiro. Se aínda é moito tempo calquera intento de optimización non axudará e deberá cambiar o seu deseño. Asegúrese de que o compilador non desoptimiza o búcle baleiro.</para>
</listitem>
<listitem>
<para>mova o código fora dos bucles internos. Un anaco de código máis complicado que se executa unha soa vez é moito máis rápido que un trozo de código máis sinxelo que se executa mil veces. Evite chamar habitualmente a código lento.</para>
</listitem>
<listitem>
<para>Forneza ao compilador tantas suxestións como lle sea posíbel. Usa a palabra chave «const». Use <envar>G_INLINE_FUNC</envar> para funcións curtas frecuentemente chamadas. Busque <envar>G_GNUC_PURE</envar>, <envar>G_LIKELY</envar> e outras macros misceláneas de glib. Use as macros no lugar de palabras chave específicas de gcc para asegurar a portabilidade.</para>
</listitem>
<listitem>
<para>Non use linguaxes de ensamblado. O código non é portábel e pode ser máis rápido nun procesador que noutro, ademais non está garantizado que sea rápido en cada procesador que admite esa arquitectura (p.ex. Athlon contra Pentium 4)</para>
</listitem>
<listitem>
<para>Non rescriba unha rutina existente dunha biblioteca a non ser que estea seguro de que é demasiado lenta. Moitas rutinas de bibliotecas de uso intensivo pola CPU xa se optimizaron. Algunhas rutinas de bibliotecas son lentas, especialmente aquelas que realizan chamadas ao sistema operativo.</para>
</listitem>
<listitem>
<para>Minimice o número de bibliotecas ás que liga. Canto menor sexa o número de bibliotecas a ligar, máis rápido se iniciará o programa. É unha tarefa difícil en GNOME.</para>
</listitem>
</itemizedlist>
<itemizedlist>
<title>Trucos de alto nivel</title>
<listitem>
<para>A ventaxa da concurrencia. Isto non significa simplemente usar varios procesadores, tamén significa aproveitarse do tempo que o usuario pasa pensando en que fará despois, para realizar algúns cálculos anticipados. Faga cálculos mentres se agarda a carga de datos desde o disco. Aprovéitese dos recursos múltiples, úseos todos á vez.</para>
</listitem>
<listitem>
<para>Engane. O usuario só ten que pensar que o equipo é rápido, non importa se realmente o é ou non. É o tempo entre a orde e a resposta o que importa, non importa se a resposta esta precalculada, cacheada ou se traballará nela en calquera momento posterior conveniente, sempre que o usuario obteña o que agarda.</para>
</listitem>
<listitem>
<para>
Do things in the idle loop. It is easier to program than using full multi-threading but still gets things done out of the users eye. Be careful though, if you spend too long in the idle loop your program will become sluggish. So regularly give control back to the main loop.
</para>
</listitem>
<listitem>
<para>
If all else fails, tell the user that the code is going to be slow and put up a progress bar. They won't be as happy as if you had just presented the results, but they will at least know the program hasn't crashed and they can go get a cup of coffee.
</para>
</listitem>
</itemizedlist>
</sect1>
</chapter>
|