Libertonia
Portada · Todo · Software Libre · Desarrolladores · Comunidad · Internet · Tecnología · Meta · Diarios
Ver: Modo: Orden:
Aprendiendo a programar | 37 comentarios (37 temáticos, editoriales, 0 ocultos)
La eficiencia (none / 0) (#22)
por jorginius ("jorginius" en Google Mail) a las Fri Jul 23rd, 2004 at 04:33:14 PM CET
(Información Usuario) http://www.rodriguezmoreno.com

Pero para los que nos preocupamos por la eficiencia, es absurdo usar un lenguaje en el que no controlas cuando se libera la memoria. ¿Y si el GC tarda en entrar? La memoria se queda ocupada. Simplemente.

¿Lo qué?, tu comentario anterior se refería a los algoritmos y la eficiencia de un algoritmo no tiene nada que ver con el recolector o que lo implementes con tal o pascual lenguaje, con o sin recolector... Como si quieres "implementarlo" con un lapiz, papel y un ábaco. La eficiencia es la misma la midas respecto a lo que la midas. ¿De qué estamos hablando?, ¿de algoritmos? ¿de código?, ¿de qué?

De todas formas, por seguir un poco el tema, el recolector tiene sus cosas buenas y sus cosas malas: la parte positiva es, aparte de la comodidad que aporta, que suele ser más eficiente que un mal programador: si éste se dedica a crear unos cuantos miles de objetos pequeños en el heap (como cadenas de caracteres o nodos de un árbol n-binario o AVL, por ejemplo) y reserva memoria por cada uno, el recolector hará un trabajo mucho mejor que él "de serie".

Y buceando un poco en los detalles, es cierto que con GC se reserva más memoria en el heap pero el sistema operativo no asigna realmente todos esos marcos hasta que la aplicación los use, y el GC ya se dará prisa en liberar recursos si escasea la memoria, así que tampoco es tanto el despilfarro.

La parte más negativa es que al no saber cuando entra el recolector, estás pillado si tienes restricciones temporales (que poco o nada tiene que ver con la eficiencia). De todas formas, existen extensiones de Java para tiempo real. Nunca las he usado y no sé como manejan el problema del GC no determinista.

¿Seguridad? Pues si, el java es muy seguro porque si no te deja hacer nada donde puedas meter la pata no metes la pata. Por el camino te pierdes el control sobre TU programa.

Bueno, si quieres meter la pata con Java aún puedes. Java te evita algunos despistes, simplifica algunas cosas que hacen más fácil que varios programadores "se entiendan" (al no haber tantas posibilidades para hacer lo mismo, la codificación de varias personas resulta semejante) y refuerza algunos hábitos buenos de programación.

Además, supongo que desde C no se ve así pero en verdad Java no es demasiado rígido. Desde luego no llega al nivel de "cuadriculación" de otros lenguajes como Ada.

A mí Java me deja frío. En realidad no he programado mucho con él: he hecho mis pinitos con el J2ME, applets y algo de programación de escritorio con gráficos junto con JDBC. Tampoco es el lenguaje que escogería para hacer programación de sistemas ni para expresar mi "vena artística" X-) pero me parece un lenguaje muy válido para "hacer programas" (que no tiene porque ser igual que "programar" :-)) y hay buenas y baratas herramientas por ahí fuera para trabajar con él. Es más adorable que otros que conozco, sin duda.

Pero los que saben lo que es un puntero se dan cuenta de que lo correcto es...

... Primero saber que quieren hacer, segundo tener claros los conceptos de qué es una referencia y que es un objeto segundo y tercero leerse la documentación del contenedor. Eso sería lo correcto, supongo :-).

Si los punteros existen y estan ahi agazapados dandote por culo, al menos que te cuenten lo que son. Y si estan ahi, ya seria un gesto que te permitan aprovecharte de ellos si quieres...

Tanto como que existen... Un puntero de C o Pascal no es más que un entero con un montón de azucar sintáctico por encima. Donde realmente hay algo que entender no es ahí, sino en el código ensamblador que genera el compilador y en cómo funciona la máquina que hay por debajo (sea real o virtual). En cualquier lenguaje que tenga instrucciones para leer/escribir en direcciones (aunque éstas se llaman PEEK y POKE X-) puedes hacer lo mismo, aunque no haya nada explicitamente llamado puntero.

Y en cuanto a lo de pasar metodos a las funciones, yo ni entro ni salgo en si tiene sentido pasar funciones como parametros.

Funciones como parámetros sí, tiene mucho sentido y es de lo más habitual. En la biblioteca estandar de C tienes ejemplos y la parte de algoritmos de la biblioteca estandar de C++ le saca mucho partido. El tema está en que los métodos pertenecen a un objeto y en teoría no tiene sentido hablar de pasar un método solo sin pasar el objeto al que pertenece. Una clase functor es lo más apropiado en un lenguaje OO.

[ Padre ]


El GC y el tiempo real (y 2. El bueno) (none / 0) (#24)
por ridiculum a las Fri Jul 23rd, 2004 at 06:16:13 PM CET
(Información Usuario)

El otro comentario no tiene un forma decente, este se lee mejor.

Se supone que los sistemas de tiempo real esta terminantemente prohibido el empleo de recolectores de basura por el indeterminismo que introducen, asi que la solucion que ofrence la RTSJ (Real Time Specification for Java) es algo similar al mlock que hay en POSIX.
Haciendo un cut && paste:

The main issue with Java derives from its foundation in object-oriented programming. The problem isn't so much with efficiency--the overhead of dynamic binding needn't be more than an extra level of indirection on the method call--but rather with the apparent unpredictability or latency incurred by garbage collection. The approach taken in the RTSJ is to allow the program to define memory areas that aren't subject to garbage collection and to define certain kinds of threads that aren't allowed to access the garbage-collected heap; such threads may preempt the garbage collector

Respecto a Ada, mejor no comentar nada, que me saldrian demasiados exabruptos :P

[ Padre ]


 
Re: La eficiencia (none / 0) (#30)
por thuban a las Fri Jul 23rd, 2004 at 09:09:26 PM CET
(Información Usuario)

Pues si tiene relacion. Es absurdo enredarse con los algoritmos si toda la memoria que puedas ahorrar machacandote para reducir las colisiones de una funcion hash y asi poder tener una zona de colisiones mas pequeña en el array, se van a perder porque por otro lado te dejas sin liberar la memoria de un auxString que creas en el interior del bucle que rellena la tabla. No merece la pena el esfuerzo. (Y si quieres una Hashtable con tratamiento decente de colisiones te la tienes que hacer tu)

Y el problema es que estas pensando en un mal programador. Como el programador es malo hacemos el trabajo por el. No le dejamos liberar memoria, ni le damos punteros... ¿No seria mejor convertir al mal programador en buen programador? Hacerle responsable de su codigo y explicarle que tiene que soltar lo que coje. Especialmente cuando aprende, como quiere hacer Gonzotba.

Y en cuanto a la seguridad del Java... Pues si, es seguro porque se supone que un lenguaje tipado y sin punteros reduce errores de programadores poco cuidadosos (otra vez) y por tanto es seguro. Pero mal codigo es mal codigo. Y despistes se pueden tener igual como en el ejemplo que he puesto (visto en el mundo real, con mas lineas por medio). Si java no me proteje de los dolores de cabeza que dan los punteros salvajes ¿que gano con no tener punteros? Peos aun. Si tengo el problema de los punteros, ¿por que nadie me cuenta que tengo el problema de los punteros?

Yo programo con java desde la version 1.0 del lenguaje, y aunque me gusta, y mucho, no me parece que sea un lenguaje para aprender a programar ni para meterse a hacer con el ciertas cosas (como arbolesB). Para eso esta el C++ o un Modula2, un lenguaje que tenga de todo y que no aisle al que aprende de la problematica de la programacion. Si no se aprende al principio, ¿cuando?

Los punteros existen aunque en Java se llaman referencias. Y eso de que cualquier lenguaje con PEEK y POKE los tiene... Pues si. Supongo que tambien se puede hacer programacion orientada a objetos en ensamblador, pero que se busquen a otro que yo me tengo que lavar el pelo...

El java no es adecuado para aprender porque pierdes todo lo que puedas aprender de punteros, la sobrecarga de operadores, la utilidad de los destructores... Menos los operadores, lo demas se puede poner en java, de acuerdo, pero ¿sirve para algo el metodo finalize? ¿Es util un destructor que no sabes cuando se lanza? ¿Puedes confiar en el para liberar una conexion a una base de datos? Con o sin pool, el problema es el mismo.

Es mas facil aprender en C++ y olvidar cosas segun el lenguaje en el que aterrices que aprender en Java y tener que aprender sobre la marcha y con prisas lo que no sabias porque java no daba.


[ Padre ]


Sintetizando (none / 0) (#32)
por jorginius ("jorginius" en Google Mail) a las Sat Jul 24th, 2004 at 01:06:20 AM CET
(Información Usuario) http://www.rodriguezmoreno.com

* Si tal y como la escribes la implementación de tu tabla hash en Java no cumple los requisitos cambia la implementación. A lo mejor es que no necesitas un objeto cadena sino un array de caracteres que sea mutable o algo así. El algoritmo puede ser bueno pero la realización no. De todas formas no se me ocurre porque tenía que no marchar en el ejemplo que pones. En el caso de que te quedes sin memoria por las cadenas auxiliares que vas creando, el recolector entrará en acción y en paz.

* No pienso en que es mejor para el mal programador, pienso en que el buen programador en ese escenario al final tendría que programar un esquema de asignación de memoria similar al que usa el GC en el lenguaje con recolector. Usar un Allocator adecuado, si usa contendores STL, que anticipe memoria para más objetos de los necesarios inicialmente y sobrecargar new para construir los objetos en esa zona. La GC no es malvada en según que casos.

* Una referencia de Java sólo sustituye parcialmente a un puntero porque no puede contener más que una dirección válida (o que lo haya sido) o nula, no nos deja modificarla aparte de asignarle otra del mismo tipo ni la expone explicitamente.

* Un lenguaje sin punteros pero con instrucciones tipo PEEK y POKE permiten lo mismo que los punteros de C y no son más puñeteras (lo digo por la comparación que me haces con la OO y ensamblador), salvo quizás porque el compilador de C hace magia y arregla la aritmética de punteros acorde con el tamaño de lo que apuntan (magia que da más problemas que otra cosa cuando por ejemplo intentas comunicar dos procesos en máquinas diferentes o portar tu código a otra máquina/compilador, pero esa es otra historia).

* En Java la única posibilidad de que una referencia apunte a un objeto que no es válido pasa porque el objeto haya pasado al limbo del recolector o le hayamos asignado explícitamente valor nulo. Un puntero de C puede apuntar a un objeto válido, a uno inválido o a cualquier sitio en cualquier momento. La mejora es evidente y la probabilidad de meter la pata por despiste en Java es menor.

* Java no tiene destructores así que no es que no sepas cuando se llaman, es que no se llaman nunca. Finalize es otra cosa distinta y si quieres liberar una conexión a una base de datos en un momento determinado, manda un mensaje entonces antes de que el objeto abandone el ámbito y pase a depender del recolector. Finalize no es para hacer esas cosas y nadie dijo que Java fuera como C++.

* Precisamente C++ es uno de los lenguajes más puñeteros de aprender, con más peculiaridades retorcidas, más formas de hacer las cosas y más puñetitas. Mucho más que C y eso ya es decir. Nunca oirás que "ya he aprendido a programar en C++" porque aprender C++ es un proceso que lleva toda una vida X-). Todo el mundo que conozco y que programa en C++ se restringe a un sub-sub-sub conjunto de lo que es el lenguaje, un subconjunto que suele coincidir bastante con Java por otra parte, sobre todo ahora que han incluido plantillas. Aprender Java primero (y orientación a objetos y una forma "sana" de organizar el código también) creo que es una buena idea para abordar C++ después.

* Para no seguir desbarrando: el padre de este hilo decía que los algoritmos sólo se podían implementar en C por los punteros. La respuesta es que que cualquier algoritmo lo puedes codificar en el lenguaje que quieras, con punteros o sin ellos. De forma más sencilla o más complicada pero los mismos algoritmos con el mismo rendimiento. Que luego corran más o menos dependerá de la máquina, del compilador o de lo listos que seamos, pero el algoritmo es el que es y no hay más que rascar.

Precisamente C es bastante malo para expresar según qué algoritmos: normalmente la expresión de un algoritmo en C suele ser bastante más complicada que la misma en otros lenguajes más "pegados" al dominio (por ejemplo comparar un algoritmo sobre un grafo en Lisp con el mismo algoritmo implementado en C).

* Esta conversación se ha ido de madre. Conmigo no cuentes para continuarla.

[ Padre ]


char[] o StringBuffer (none / 0) (#33)
por jorginius ("jorginius" en Google Mail) a las Sat Jul 24th, 2004 at 01:34:14 AM CET
(Información Usuario) http://www.rodriguezmoreno.com

Si tal y como la escribes la implementación de tu tabla hash en Java no cumple los requisitos cambia la implementación. A lo mejor es que no necesitas un objeto cadena sino un array de caracteres que sea mutable o algo así.

El "algo así" podría ser un StringBuffer. Y ya puestos... Me comí un ":-D" al final del mensaje anterior y sin eso parece como si estuviera rebotado. Vamos, que aunque se salga de madre yo seguiré contestando, me temo :-).

[ Padre ]


 

Aprendiendo a programar | 37 comentarios (37 temáticos, editoriales, 0 ocultos)
Ver: Modo: Orden:
Menu
· crear cuenta
· FAQ
· búsqueda
· Fuentes de Noticias

Login
Nueva cuenta
Usuario:
Contraseña:

ecol Logo Powered by Scoop
Todas las Marcas Registradas y copyrights de esta página son propiedad de sus respectivos dueños.
Los comentarios son propiedad del que los escribe.
Los iconos de las noticias y el logotipo son propiedad de Javier Malonda.
El Resto © 2002 Escomposlinux.org y aledaños.

Puedes sindicar los contenidos de libertonia en formato RSS 1.0 y RDF 0.9. También se puede sindicar la cola de envíos pendientes de moderación.

El proyecto escomposlinux.org está dedicado a la memoria de tas

crear cuenta | faq | búsqueda