Está en la página 1de 8

INSTITUTO TECNOLOGICO DE MINATITLAN

DOCENTE: Ing. Sylfra Avedaño Romero

ALUMNO: Jiménez García Iván de Jesús

ASIGNATURA: Programación

TEMA: Modularidad

ING. QUÍMICA

GRUPO: “D” SEMESTRE: “1” UNIDAD: 4


4.1 Optimización de código.

En los primeros tiempos de la informática, programar exigía utilizar lenguajes muy


próximos a la plataforma de ejecución. El código máquina o el lenguaje ensamblador
permiten un control muy fino del proceso de ejecución: cómo se asignan los
registros del procesador, cómo se almacenan los datos y se accede a la memoria.

La optimización de código es el
conjunto de fases de un
compilador que transforman un
fragmento de código en otro
fragmento con
un comportamiento
equivalente y que se ejecuta de
forma más eficiente, es decir,
usando menos recursos de cálculo como memoria o tiempo de ejecución. Es
importante destacar que:

 La condición de tener un «comportamiento equivalente» es bastante


onerosa, ya que incluye también situaciones de error donde el
comportamiento debe ser el mismo. Pongamos como ejemplo una
instrucción como «x = y / y«. La tentación es substituir esta expresión por «x
=1«, pero es necesario garantizar que la variable y no puede ser igual a 0,
porque entonces el código podría tener un comportamiento diferente según
el lenguaje (p.ej. división por cero).

 También es fundamental garantizar que el código no será menos eficiente


que antes de optimizarlo. Por ejemplo, el desenrollado de bucles (loop
unrolling, replicar N veces el código de un bucle) puede reducir el tiempo de
ejecución al simplificar instrucciones innecesarias (p.ej. saltos), aunque al
hacerlo puede hacer crecer el tamaño del código. Dado que el tamaño del
código puede tener consecuencias a nivel de acceso a caché y a la memoria,
podría pasar que el programa optimizado acabara siendo más lento que el
original.

Existen diferentes técnicas para optimizar el código, cada una de las cuales intenta
mejorar un aspecto diferenciado del código. En general pueden clasificarse en dos
categorías, las de flujo de datos (data-flow) y las de flujo de control (control-flow).
Las optimizaciones del flujo de datos pretenden mejorar la eficiencia de los
diferentes cálculos realizados en el programa: precalculando expresiones con valor
conocido en tiempo de compilación, reaprovechando cálculos ya realizados en otras
partes del código o suprimiendo cálculos innecesarios. Por contra, las
optimizaciones del flujo de control intentan utilizar las instrucciones de salto
condicional e incondicional de la forma más eficiente posible (ya sea desplazando
código o eliminando saltos innecesarios). Puede definirse también una tercera
categoría, las optimizaciones de bucles (loop optimization), intenta mejorar el
rendimiento de las instrucciones iterativas como for, while … do o repeat … until.
En este caso, los cambios realizados al código del bucle afectan tanto al flujo de
datos como al flujo de control.

La ventaja de todas estas técnicas es que se aplican de forma automática cada vez
que compilamos nuestro código, de forma que podemos centrarnos en hacer
nuestro código legible en lugar de intentar optimizar «a mano». Como dijo Donald
Knuth, «la optimización prematura es la raíz de todos los males». Dejemos a los
compiladores los detalles de bajo nivel y dediquémonos a diseñar un buen
algoritmo, que ya es un trabajo suficientemente complejo.

4.2 Descomposición funcional (top-dow).

La descomposición funcional se refiere ampliamente al proceso de resolución de


una relación funcional en sus partes constituyentes, de tal manera que la función
original se puede reconstruir (es decir, recompuestos) de las partes en función de
la composición. En general, este proceso de descomposición se lleva a cabo ya sea
con el fin de hacerse una idea de la identidad de los elementos constitutivos (que
pueden reflejar los procesos individuales de física de interés, por ejemplo), o con el
fin de obtener una representación comprimida de la función global, una tarea que
sólo es posible cuando los procesos constitutivos poseen un cierto nivel de
modularidad (es decir, la independencia o no de interacción).

Top-down, significa, partir de lo más general hacia lo más detallado. es un proceso


análogo al de armar un rompecabezas en el sentido de ver primero la imagen ver
primero el concepto o la imagen general, y a partir de alli comenzar a detectar dónde
va cada pieza dentro de la imagen. la diferencia es el recorrido jerárquico y modular
que se realiza en su elaboración.
Un módulo es un subsistema que agrupa funcionalmente programas, objetos,
herramientas y , bases de datos según su funcionalidad y objetivos vinculantes. por
ejemplo, el objetivo de un módulo de nómina es generar el pago a los empleados,
el objetivo de un módulo de compras es proveer a a la empresa de material
necesario para su funcionamiento y así sucesivamente.
Top Down La programación descendente o "Top - Down" es el proceso mediante
elcual un problema se descompone en una serie de niveles o pasos sucesivos
derefinamiento (stepwise). El diseño descendente es una técnica que permite
diseñar la solución de unproblema con base en la modularización o segmentación
dándole un enfoque dearriba hacia abajo (Top Down Design). Esta solución se
divide en módulos que seestructuran e integran jerárquicamente, como si fuera el
organigrama de unaempresa.
En el diagrama anterior se muestra la estructura del algoritmo ALGO, quese auxilia
de tres módulos subordinados, cada
uno de los cuales ejecuta una
tareaespecifica. En su momento el
modulo principal ALGO invocara o
llamara a losmódulos subordinados, es
decir, dirigirá su funcionamiento. Un modulo es un segmento, rutina, subrutina,
subalgoritmo oprocedimiento, que puede definirse dentro de un algoritmo con el fin
de ejecutaruna tarea especifica y puede ser llamado o invocado desde el algoritmo
principalcuando sea necesario.
4.3 Rutinas, Funciones y Procedimientos.
En general un problema complejo puede ser resuelto de manera más fácil y eficiente
si se divide en problemas más pequeños y concentrándonos en cada etapa en la
solución de ese "subproblema".

Esto implica que el gran problema original será resuelto por medio de varios
módulos, cada uno de los cuales se encarga de resolver un subproblema
determinado. Esos módulos, se conocen con el nombre de subalgoritmos.

Los subalgoritmos se escriben sólo una vez, luego es posible hacer referencia a
ellos ("llamarlos") desde diferentes puntos de un pseudo código. La ventaja obvia
es que nos permite reuGlización y evita la duplicación de códigos.

Los subalgoritmos pueden ser dos Gpos: Funciones y Procedimientos (también


llamadas subruGnas o subprogramas).

Una función es una expresión que toma uno o más valores llamados argumentos y
produce un valor que se llama resultado. Este resultado es además, único.

Ejemplos de funciones matemáGcas son los logaritmos, funciones trigonométricas


(seno, coseno, etc). • Una función puede devolver un resultado que puede ser una
cadena, un número o un valor de Gpo lógico (verdadero o falso)

Esto hace que en los lenguajes de programación, debamos especificar de qué Gpo
es una función. Una función será de Gpo numérica cuando devuelva un número y
será de Gpo alfanumérica o string cuando devuelva una cadena

La llamada a una función será siempre: variable ß nombre_funcion (parámetros)

La llamada a una función MES que devuelva el nombre del mes, pasándole el valor
numérico correspondiente será: nombre_mes ß MES(2) (esto devolvería "Febrero")
4.4 Paso de argumentos.

En ciencias de la computación, un parámetro es una variable utilizada para recibir


valores de entrada en una rutina, subrutina o método. Dichos valores, que serán
enviados desde la rutina invocante, son llamados argumentos. La subrutina usa los
valores asignados a sus parámetros para alterar su comportamiento en tiempo de
ejecución. La mayor parte de los lenguajes de programación pueden definir
subrutinas que aceptan cero o más argumentos.

Existen cinco formas de pasar un argumento a una función (subrutina)


o procedimiento: por valor, por referencia, por resultado, por valor-resultado y por
nombre.

Paso por valor

El paso de parámetros por valor consiste en copiar


el contenido de la variable que queremos pasar en
otra dentro del ámbito local de la subrutina, consiste
pues en copiar el contenido de la memoria del
argumento que se quiere pasar a otra dirección de
memoria, correspondiente al argumento dentro del
ámbito de dicha subrutina. Se tendrán dos valores
duplicados e independientes, con lo que la
modificación de uno no afecta al otro.

Paso por referencia

El paso de parámetros por referencia consiste en proporcionar a la subrutina a la


que se le quiere pasar el argumento la dirección de memoria del dato. En este caso
se tiene un único valor referenciado (o apuntado) desde dos puntos diferentes, el
programa principal y la subrutina a la que se le pasa el argumento, por lo que
cualquier acción sobre el parámetro se realiza sobre la misma posición de memoria.
El paso de la dirección de memoria debe ser transparente al programador. Los
lenguajes que permiten tratar con direcciones de memoria, como C, permiten
simular el paso de argumentos por referencia, sin disponer realmente de esta
característica.

Paso por valor resultado

Es un tipo poco usado en los lenguajes de programación actuales. Se basa en que


dentro de la función se trabaja como si los argumentos hubieran sido pasados por
valor pero al acabar la función los valores que tengan los argumentos serán
copiados a las variables que pertenecían.

Este tipo puede ser simulado en cualquier lenguaje que permita el paso de valores
por referencia de la siguiente forma:

void EjemploValorRes(int& a1, int& a2, int& a3) {

int aux1 = a1, aux2 = a2, aux3 = a3;

// código trabajando con aux1, aux2 y aux3

a1 = aux1; a2 = aux2; a3 = aux3; // Dependiendo del compilador la copia se realiza


en un sentido o en el otro

Tal y como indica el ejemplo de simulación de valor-resultado, el orden de copia


depende del compilador, lo que implica que la misma función pueda dar resultados
diferentes según el compilador usado.

Aquí se exponen unos ejemplos que demuestran las diferencias de estos tipos:

void función(int a, int b) {

++a;

b += 2;
}

int a = 0;

función(a, a);

 Argumentos pasados por valor: a = 0

 Argumentos pasados por referencia: a = 3

 Argumentos pasados por valor-resultado:

o Si el compilador copia los resultados de derecha a izquierda: a = 1

o Si el compilador copia los resultados de izquierda a derecha: a = 2

También podría gustarte