Publicado hace 5 años por oraculus_reloaded a stackoverflow.com

Si reemplazo 2 * (i * i) por 2 * i * i, se tarda entre 0.60 y 0.65s en ejecutarse. ¿Cómo es posible?

Comentarios

D

#15 demasiado subjetivo lol. Está hecho por alguien que ama Java, se ve.

D

#25 Java es para dummies,conviértete,ven al lado oscuro.

D

#15 No soy informatico y de lenguajes se mas bien poco. Pero, y lo que me he reido

j

#15 Lo que tu quieras con PHP pero es uno de los lenguajes mas utilizados para desarrollo web. Los CMS mas populares ya sea wordpress, drupal, joomla o para ecommerce prestashop, magento estan desarrollados en php

D

#37 Django ...

D

#65 buena pelicula

SiCk

#37 Como Facebook, la wikipedia, yahoo.... no sé, cosas de empresas pequeñas y medianas.

D

#71 facebook usa una extensión de Php llamada hack.
De yahoo ni idea de donde lo has leido,es dificil encontrar información de algo que esta muerto.

demostenes

#37 Discrepo

D

#98 hay muchísimas en gittheprincess,esta me marco en la uni,es una versión algo mas antigua.

D

#15 Falta Python:

from castle import Princess

Y te sobra una viñeta para escribir un readme y un script de instalación con más líneas que la propia aplicación y subir el paquete a PyPI para que no lo descargue nadie

m

#15: Deberían parodiar a Phyton también, que tiene mucho que pwnear, por ejemplo, que la estructura va en la indentación, ideal para copiar y pegar en según que entornos, además de que es más fácil liarse si tienes que añadir cosas anidadas.

heffeque

#15 Yo sí voy a añadir algo (los "=" se ven un poco mal)

D

porque java apesta

#killJava

D

#1 antes me caías bien,pero veo que eres un tio con un gusto cuestionable.

D

#7 PHP y JavaScript te envían un abrazo.

D

#12 Los mayores no usamos juguetes.

D

#13 me he liado con REACT al final jajaja

skaworld

#14 Tiene cojones que se queje la reinona de java y esté mirando javascript lol

D

#17 homeeeeeeeeee, no tiene nada que ver uno con el otro eh!

skaworld

#24 Lo se pero amos quejarse de java desde otro lenguaje de tipado debil lol

D

#29 cariño me sumo a las modas, y la moda ahora es odiar Java. Pues no se hable más, odio Java.

jajaajaj

b

#29 Otro? ... Java no es de tipado debil.

D

#17 #24 yo con el puto javascript me pillé vicio..... lol llamame raro,....

skaworld

#82 Eso está muy bien, un primer paso es reconocerlo, pero no debería quedarse ahí y deberías buscar ayuda.

D

#85 Si, lo dejé de lado y me he vuelto a mis grandes integraciones (Java / C++ ) que me va más la marcha de millones de registros, horas de proceso, y esas cosas... Lo del javascripy esta mas que bien para fumar unos canutitos en casa y "disfrutar"

lol

PD: Compré hace mucho el dominio "JacaScript.net"

skaworld

#86 "JacaScript.net" ...

Si esto no es motivo de strike por incitacion al odio, yo ya no entiendo esta web

lol

D

#88 mira que cerca estan la v y la c

PD: Soy de jaca

p

#17 me imagino que #14 lo dira porque javascript a palo seco es mas guarro que una peli porno alemana de enanos cagandose en el pecho. Con estas librerias como que se queda el lenguaje un poco mas apañado, aunque siga siendo el hermano feo de frankenstein. lol

skaworld

#75 Creo que le debes un poco de respeto a la coprofagia acondroplasica germana, un género lleno de matices y sutilezas que no se merece tal desprecio

Caresth

#11 Corrigiendo mi comentario y el tuyo, la diferencia la mide al correr un programa que hace la operación mil millones de veces. Vamos, que para cada iteración viene siendo bastante desdeñable. Eso no quita, como dice #13, que sea una diferencia en un programa muy sencillo, y que en temas complicados sí sea apreciable.

kmon

#1 #13 a ver, que estamos hablando de 0.10 segundos en 1000000000 iteraciones, el tiempo de 1000 millones de multiplicaciones

D

#13 yeah ... .asi me gusta baby. U think clearly.

PD: #1 cariño, si no te justa por el java, pues por el awk.

D

#13 Estoy seguro cualquier aplicación hará aguas por muchísimas partes antes que esto sea un problema real. Esto tiene un nombre y es el de micro optimizaciones.

d

#1 programa en Rails!!!

D

#1 Ya me jodería odiar el lenguaje que se ha convertido en el estándar de la industria....

D

#61 se ha convertido ahora que deja de serlo...

i

#1 Aplaudo su detallada argumentación

KimDeal

#1 mis dieses.

S

#6 o metido en un loop.

J

#38 en la noticia ya esta en un loop, pero 0,10 segundos puede ser mucho dependiendo de lo que estes calculando. Por ejemplo, en un videojuego, 0,10 segundos en tus cálculos es mucho tiempo.

s

#44 0.10 en mil millones de iteraciones.
Vamos, lo que viene siendo una diferencia al mover una fresita en un juego de mover frutas de quizá un milisegundo.
Optimiza ahora todos los i*i para pasarlos a (i*i) para ahorrar ese milisegundo...

J

#47 no se que medidas tomas tu, pero 0,10 no es un miliseguno, es 1/10 segundos o lo que es lo mismo 100 milisegundos. En juego a 30 frames/segundo (33ms cada frame) estamos hablando de 3 frames que pierdes en mover la fresita.

s

#50 el milisegundo me lo he sacado de la manga. La diferencia de 0.10 segundos se da en 1000 millones de iteraciones. Si tú mueves la fresita cambiando la "x" y la "y" en una cuadrícula 2D de píxeles, y la calculas en un bucle que tenga en cuenta todos los píxeles de la imagen a mover, tendrás unos pocos cientos (miles como mucho) de iteraciones. Por tanto la diferencia será prácticamente despreciable y por eso me saco de la manga el milisegundo en una app. En realidad el movimiento de X e Y lo tendrás parametrizado de algún modo, así que ni tendrás que iterar sobre la matriz de píxeles.

Si tú estás trabajando en un juego en HD para video consola ese desfase quizá, sólo quizá, fuera apreciable en casos muy extremos... pero dudo mucho que lo fuera. Francamente lo dudo... además, nunca hemos visto en videojuegos cosas como que haya monigotes que atraviesen paredes o se queden "atorados" en bordes geométricos...

Y si estás trabajando en determinados proyectos muy, muy concretos que exijan un enorme número de operaciones matemáticas en tiempo real (francamente, no se me ocurre ninguno...) pues tal vez se note.

s

#74 Correcto. Algo parecido digo en #60.
Pero no implica que en la grandísima mayoría de ocasiones la diferencia es despreciable.

Más aún, si tienes que analizar todos los problemas del compilador (probablemente esto es un problema del compilador ya que no hay ninguna razón lógica para ello) para casi cualquier operación del programa nunca acabarías el programa.

Premature optimization is the root of all evil.

D

#60 Suscribo tu comentario, pero es que aunque este problema sea algo apreciable, lo más probable es que tu programa haga aguas por cualquier otra parte por otro motivo y con un mayor impacto. En general en este meneo se cae en una falacia de agregar números insignificantes hasta llegar a cantidades monstruosas.

Ejemplo: si todas las personas del mundo dejan un arroz en su plato sin comer, si sumamos un arroz por toda la población mundial, cada día, a lo largo de un año tendrás toneladas de comida... sin embargo, eso no significa que realmente puedas alimentar a nadie con ese grano de arroz.

D

#50 la Fresita no creo que haga mil millones de operaciones aritméticas como la descrita, no es realista y significaría que el juego está muy mal hecho.

J

#68 Imagina que en vez de mover la fresita, estas moviendo la cámara de un juego 3D, y no tienes una fresita sino un millón, y el calculo es similar pero mas complejo.

D

#74

la camara no la mueve la cpu, la mueve la gpu, ya que los calculos relacionados con la camara y la perspectiva son altamente paralelizables. Son operaciones de matrices que realiza la gpu en paralelo de forma masiva.

Que en java 2*(i*i) sea mas rapido que 2*i*i es irelevante para la programación de la imnesa mayoría de los programas informáticos, juegos incluídos.
Incluso en el procesado masivo de datos, en la lista de cosas a invertir el tiempo para reducir el coste del procesado, esto estaría por el final, compardo con problemas de I/O, estructuras, etc.

#81

PD: Tú nunca conseguirás mejorar el rendimiento de un programa Java, por lo que parece,.....

Me dedico entre muchas otras cosas, a mejorar el rendimiento de programas informáticos a cambio de dinero.

https://github.com/eyeos/spice-web-client

Eso es una tarjeta gráfica 2d programada por mi en javascript, alcanza 60fps procesando llamadas similares a gdi (otra api, pero es lo mismo). Algo de rendimiento se, y creeme, 2*i*i vs 2*(i*i) es completamente irrelevante.

https://stackoverflow.com/questions/43513975/awk-gawk-performance

El problema de ese tipo de posts, es que ese no es el caso de uso de la mayoría de la gente, y para la gente que ese es el caso de uso, hacen las cosas bien. Es ridículo que un programador cree un programa a mano en java para parsear un xml de gigabytes.

Obviamente lo estás haciendo muy mal si acabas haciendo eso. Gestionar grandes volumenes de datos es algo que ya está inventando, y si lo estás reimplementando en tu programa en lugar de utilizar spark+hadoop/mysql/mongo/etcetcetc es que lo estás haciendo muy, muy mal.

Por no hablar del hecho de que las máquinas no escalan verticalmente hasta el infinito, y que esas soluciones ya implementadas de las que te hablo, permiten ser distribuidas horizontalmente, además de resolverte muchos otros problemas, para que tu te centres en hacer algo útil, y no en reinventar la informática básica.

Sobre tu segundo post:

https://brenocon.com/blog/2009/09/dont-mawk-awk-the-fastest-and-most-elegant-big-data-munging-language/

Conozco muy bien las bondades de awk, pero que tiene que ver eso con microptimizaciones tipo 2*(i*i) vs 2*i*i que además luego se rompen, y se vuelve mas lenta la que era rápida, y rápida la que era lenta?

En resumen:

1. la mayoría de programadores no tienen que reinventar programas ya inventados de manipulación másiva de datos. Solo necesitan reutilizar servicios/librerias de terceros para ese tipo de operaciones de escala. De hecho, de hacerlo en tu programa seguramente lo estás haciendo mucho peor que los programas ya hechos que hacen eso.

2. Si en tu programa aparece el problema de trabajar con xml de gigas, planteate bien como estás haciendo las cosas. Probablemente lo mas inteligente no sea probar si con 2*i*i ganas unos segundos, sino dejar de hacer las cosas de forma que termines con problemas tan poco reducidos en una sola máquina

3. Cuando tus problemas no sean reducibles, y tengas que afrontar esos volumenes, no solo vas a necesitar programas ya hechos que te ayuden a mover ese volumen de datos de forma eficiente, sino que además vas a necesitar escalar en horizontal, y ahí es donde spark te va a ir muy bien (o mongodb, que tiene un map reduce bastante bueno, aunque casi nadie lo use)

Es decir, que en para un programador medio, 2*i*i vs 2*(i*i) es algo intrascendente en los problemas que tiene que resolver, e incluso para un programador trabajando con grandes volumenes de datos, es igual de intrascendente.

J

#95 Que la cámara la mueva la GPU no quiere decir que la CPU no haga nada, por ejemplo, calcula colisiones, físicas, IA, lógica en cada draw call. Sino los juegos de ahora, no estarían pidiendo monstruos de 4 nucleos a frecuencias altas.

Yo no estoy discutiendo que este ejemplo se vaya a dar en el mundo real o merezca la pena esa optimización (sinceramente casi nadie programa juegos en Java ya, quitando Android, pero incluso en Android me suena que existe otra api alternativa). Lo que estoy diciendo es que aunque 100ms puedan parecer poco tiempo, es mucho en algunos ámbitos como pueden ser los juegos.

D

#96 el motor de física no se mueve como respuesta al movimiento de la camara. El motor de física es siempre un bucle aparte, en un thread aparte. Si no fuese así, cuando la escena se redenriza mas rápido, la física se movería mas rápido, lo cual no tiene sentido.

El movimiento de la camara del que hablas en #74 es claramente un mal ejemplo.

Si de lo que hablas es de los cálculos de física de un juego, de nuevo, nunca va a tener millones de entidades en la pantalla, por que antes de tener problemas solventables con 2*(i*i) vs 2*i*i, has petado por miles de otros problemas, como el recolector de basura o mil problemas mas. Por eso, en cualquier engine moderno millones de entidades se gestionan a través de sistemas de partículas acelerados via gpu con physx o gestionados con otro tipo de estrategias aproximativas.

En serio, 2*(i*i) vs 2*i*i es irrelevante para la inmensa mayoría de personas del planeta, programadores incluidos.

Piensa que poner 2*(i*i) por que va mas rápido es hacer un programa a medida del compilador/vm. Y hacer un programa a medida del compilador es algo caro de mantener. El compilador cambia, y para que tu programa siga igual de rápido, tendrás que seguir adaptandolo a medida de cada versión del compilador/vm.

Por eso, la mayoría de programas solo necesitan estar hechos a medida de una computadora digital electromagnética moderna, y no a medida de una versión superespecifica de una máquina virtual o un compilador.

De hecho, al imensa mayoría de programas informáticos no necesitan ni estar hechos a medida de un computador digital electromagnético, sino simplemente mover los datos de forma lógica y con sentido común, y entender bien como gestionar la entrada/salida. Solo con eso, puedes acelerar programas cientos de veces, y ganar una fortuna de ello en consultoría.

Entiendeme, para los que nos dedicamos profesionalmente al rendimiento, esto es irrelevante, para los que se dedican a crear programas normales, es también irrelevante.

J

#97 Ya te puse en el anterior comentario que era solo un ejemplo, y que no hablaba de esta optimización en particular, sino de que 100ms para una persona común puede parecer una cantidad de tiempo ínfima, pero por ejemplo, en un videojuego puede ser la diferencia entre una tasa de fotograma estable o no.

En cuanto al motor de física, hay todavia juegos que van asociados a la tasa de fotogramas, ejemplo? La saga fallout, la saga dark souls. No son juegos indie precisamente.

s

#97 De hecho, a mi juicio, esto sólo es importante para los que hacen compiladores...

a

#96 el problema no es que un juego pida mucha máquina (que también) El verdadero problema es que una web con 3 divs y dos .js te piden 8 núcleos lol

D

#96 Que conste que en general tienes razón en tu comentario, pero es que si te pasa eso, seguro que hay cambios insignificantes que tienen mayor impacto en tu juego. De hecho si te pones a optimizar cualquier cosa en ensamblador seguramente consigas arañar alguna operación más y algún nanosegundo más.

D

#81 Resumen de #95

El rendimiento importa y yo me dedico a ello, pero nunca el rendimiento depende de microoptimizaciones de maquina virtuales o compiladores, sino de gestiones adecuadas de los datos a nivel conceptual, y adaptar un poco el programa a las capacidades y forma de funcionar de una computadora electromagnética.

D

#100 No, no depende, no. ...

Pues menos mal que te dedicas a optimizar rendimiento...

D

#95 a ver majo, que pegues este link -> github.com/eyeos/spice-web-client no dice nada.


En resumen:

1.- Vas de listo
2.- Nadie ha hablado de reinventar
3.- Me lo vas a decir tu que llevo 15 años trabajando en sistemas de tarificacion de movil...... Me lo vas a decir tu que he diseñado el sistema de intercambio de datos de factura de vodafone.. me lo vas a decir tu que he estado en la fusión ono vodafone...


Llegó el listo, hablándome de MongoDB.... llegó el cuñado...

leitzaran

#50 Es 0,1 segundos en 10^9 iteraciones. Rehaz tus cálculos.

D

#47 si te la pela el i * i como desarrollador, no creo que hayas dado importancia al resto del código, así que imagínate.

t

#9 Si tienes que hacer semejante número de operaciones en bucle como para notar este tipo de cosas, me da a mí que el buen programador buscaría una herramienta mejor para hacerlo que a pelo en Java. Algo tipo CUDA, o alguna librería para cálculo masivo.

D

Viene al caso

t

#51 No permitió que funcionase, permitió liberar el código sin problemas legales, porque el algoritmo "clásico" tenía una patente en vigor.

Lo cual demuestra que John Carmack es el puto amo, básicamente.

J

#52 No lo escribió él. Pero me parece muy elegante la solución.

M

#20 He cambiado 2 * i * i por 2* (i*i) en mi aplicación y ahora mis relaciones con las mujeres son mucho más fructiferas, mi cabello tiene más fuerza y volumen y resucitó a mi gatito. Nunca podré agradecer del todo esta mejora.

Kenzoryyy

#20 y que tal iria esta? > ||*|| mas rápido no se, pero igual tu aplicación se independiza en cuanto no te des cuenta lol

P

Siempre me lo habría preguntado pero nunca me atreví a hacerlo. Gracias.

Si esto no llega a portada yo ya no sé que va a llegar.

D

#5 lol

D

#5 Sé que no lo has dicho, pero como bien dices entre líneas esto es lo que pasa cuando se permite que un populista llegue a venezuela como presidente. Disfruten lo votado.

D

#2 tortilla de patatas con grafeno y cebolla dentro de un opel corsa,eso no fallaría nunca.

m

#2 que esto llegue a portada significa que menéname son "machos" informáticos en un 80% lol

hamahiru

Me encanta el olor a Meneame ClassicTM por la mañana.

D

#22 hay que revindicarlo más. Eso, o seguir con noticias de VOX

numero

Muy bueno. El tener conocimiento de estas cosas, y ahorrar varios segundos de ejecución en un programa, diferencia de un programador de un buen programador.

D

#3 La diferencia de tiempo de ejecución es de 0,10 segundos; eso no es ser un buen programador, es tener demasiado tiempo libre.

D

#4 quizás esta de mantenimiento,entonces tiene tiempo de sobra para hacer eso,si se descuenta algo de tiempo de su hora de café(8 horas al día)

frg

#4 Todo depende de qué estés progamando, y de cuantas veces realices operaciones similares.

D

#4 Depende de lo que programes.

Yo estoy ahora mismo con aplicaciones donde hay un tiempo de ciclo de 20ms.
100 milisegundos es una aplicación que no funciona.

D

#4 0,10 segundos es una burrada y no, es menos.

J

#4 0,10 segundos en un algoritmo iterativo complejo con muchos cálculos, se pueden convertir en algunos segundos ;).

0,10 segundos en un calculo en tiempo real necesario en un videojuego es ralentización segura.

D

#4 Eres un mal programador.

Poignard

#4 Seguro que trabajas haciendo webs para algun organismo público, eh gañan!

D

#33 Pues no sabría qué decirte, el compilador lo puedes configurar para que se comporte de muchas maneras al compilar. Por ejemplo en una evaluación tipo (funcion1() && funcion2() && funcion3()) en la que cada una de las fuciones devolviese un booleano puedes hacer que el compilador ejecute las 3 funciones y después ejecutar la evaluación, pero también puedes configurarlo para que vaya ejecutando ambas cosas a la vez y en ese caso en ciertas ocasiones funcion3 no llegaría a llamarse nunca dando lugar a un código con mejor rendimiento (pero que te puede perjudicar si las necesidades de tu programa necesitases que las 3 funciones se ejecutasen siempre, en cuyo caso te verías obligado a escribir el código de otra manera.

No digo que se el caso de ejemplo, pero en la práctica en el primer ejemplo el programador no le da ninguna pista al compilador de forma que primero hace 2*i y luego el resultado *i. En el segundo caso sin embargo le estas dando una pista i*i tiene que ejecutarse antes de multiplicar por 2. El compilador puede entonces deducir que i*i es lo mismo que i^2. Si el compilador, por el mecanismo que sea, fuera capaz de calcular operaciones tipo n^2 más rápido que a*b el resultado es un código más optimizado.

t

#3 Teniendo en cuenta que es un fallo de la máquina virtual, más que dedicar tiempo a optimizar esto lo eficiente es reportarlo, y esperar a la siguiente versión de la máquina virtual que arregle el problema.

R

#57 No se si se puede llamar un fallo. Es mas bien una falta de optimización durante la compilación

squanchy

#3 Hombre, este ejemplo quizás sea un poco excesivo, pero sí que ves mala praxis a diario. Gente que declara variables dentro de bucles que se ejecutan miles de veces o que concatenan cadenas enormes con el operador +=

D

#62
Int valor = 0;
a=getValorFromservicio();
if (a==1)
if(a==2)

if(a==3)


if (a!=1 && a!=2 && a!=3)




¿Te gusta eh?


C

s

#80 La lógica, en tu ejemplo, es, a mi juicio, mucho menos problemática que no declarar los enteros como constantes con un nombre descriptivo para saber a qué se refieren....

parrita710

#62 Pues parece que en Java es un poco mas eficiente el caso de declarar las variables dentro del for
https://stackoverflow.com/questions/407255/difference-between-declaring-variables-before-or-in-loop

D

#3 me dedico a esta industria hace mucho tiempo, y este tipo de cosas no solo no diferencia a un buen programador de un mal programador, sino que suele ser al revés.

Los buenos programadores saben que lo más importante es estructurar el programa de forma correcta, y que como consecuencia de una buena estructura, se obtiene mayor rendimiento, escalabilidad y seguridad, simplemente por qué un programa estructurado correctamente, cambiar cosas es muy fácil, y donde ponia 2*I*I mañana pone otra cosa, sin casi ningun coste.

Mientras tanto, el programador Junior hace programas de mierda, que no se pueden mantener ni extender según se necesite, pero habitualmente habla del rendimiento y de este tipo de trucos específicos de la plataforma.... Como si ese tipo de cosas, fuesen a cambiar el hecho de que mantener y extender su programa es un infierno, y que cuando aparezcan nuevos truquitos de la plataforma, el no podrá aplicarlos fácilmente a su programa, mientras que los programadores expertos con programas mantenibles y extensibles si podrán.

D

#67 Nada, el performance no importa

https://stackoverflow.com/questions/43513975/awk-gawk-performance

O el elegir correctamente una distribucion de un lenguaje u otra, tampoco

https://brenocon.com/blog/2009/09/dont-mawk-awk-the-fastest-and-most-elegant-big-data-munging-language/

Nada.... tu sigue a lo tuyo.....


Para mi un mal programador es el que cree que una cosa es más importante que la otra y no valora que todas estaán conectadas y afectan al resultado final....

PD: Tú nunca conseguirás mejorar el rendimiento de un programa Java, por lo que parece,.....

selufett

#67 Tenéis los dos razón.. ambas prácticas son buenas. Y no necesariamente hacer hincapié en una u otra te hace mejor o peor programador.

albandy

Basicamente porque multiplicar por 2 es extremadamente fácil y cuanto más grande sea el número a multiplicar por 2 más tiempo ahorrará.
Supongamos que multiplicar x2 es un 10% más rápido que multiplicar por cualquier otro número.
La multiplicación tiene un coste (hay bastantes mov, push cambios de registro etc...)
Si yo multiplico 2x500x500 primero hago 2x500=1000 y luego 1000*500 Nos queda que el numéro más grande no se ultiplica por dos
En cambio si yo multiplico (500x500) tengo 250000 y luego lo multiplico por 2 por lo que la operación más costosa la hago con el multiplicador más fácil para la máquina.

t

#30 Salvo que te estés saliendo de rango y necesites un tipo más gordo, cuesta el mismo tiempo/recursos multiplicar 2x2 que 2.000.000x2.000.000. Los circuitos no funcionan así.

albandy

#55 Cuando multiplicas por 2 solo haces 1 mov

1 --> 1 * 2 --> 10
2 --> 10 *2 --> 100
3--> 11 * 2 --> 110
4-->100 *2 --> 1000

t

#58 Sí, multiplicar por dos se resuelve con un desplazamiento, pero en este caso esa no puede ser la solución, ya que, con paréntesis o sin ellos, tienes que hacer las mismas operaciones: un desplazamiento y una multiplicación. Y la multiplicación tarda lo mismo, sea con números grandes o pequeños.

Al final, la respuesta está en el propio enlace: simplemente el optimizador de código es mierder y en un caso no optimiza lo suficiente. Probablemente en alguna versión posterior lo mejoren, y se resolverá el tema.

albandy

#58 #55 Y si no recuerdo mal la instrucción era shl o algo así, la que no rota (hace muchos años ya que hice ensamblador en ingeniería informática).

t

#64 shl (shift left) desplaza a la izquierda y por tanto multiplica por dos, y shr desplaza a la derecha y divide por dos. Puedes multiplicar dividir por una potencia de 2 (2, 4, 8...) a coste casi cero. En cambio, multiplicar son unos cuantos ciclos.

Obviamente el tema sólo vale para enteros, para floats y compañía no cuela el truqui.

D

#55 No tiene por qué costar el mismo tiempo. Dependerá de la capacidad de representación de números que tenga tu procesador, de la memoria que tenga... etc... No todos los circuitos funcionan igual.... ni todos los procesadores calculan mediante los mismos algoritmos...

t

#84 Ya he dicho que si te sales del rango la cosa puede cambiar, pero aquí hablamos de un int que, en Java, es un mundano número entero de 32 bits. Dos multiplicaciones de dos números de 32 bits tardan exactamente lo mismo, independientemente del valor, en cualquier procesador desde el 386 hasta un Core i9.

Otra cosa es que hablemos de números muy tochos, en plan BigInteger y tal, que ya son objetos y la cosa puede depender de la implementación. Pero con tipos básicos no hay diferencia, al circuito le da igual si de esos 32 bits usas todos o sólo unos pocos. Él multiplica todos igual, en paralelo.

R

#30 El problema no viene por ahi. Estoy convencido que estoy pasa tambien si en vez de multiplicar por dos multiplicadas por tres. Internamente, la JVM esta pensada como una maquina de pila, no de registros. Cuando conviertes ese código a código nativo, acabas generando código que utiliza una cantidad muy pequeña de registros.

Muy por encima (en pseudoensamblador), imagino que la opción rápida hace:
MOV RAX [i]
MUL RAX, RAX, RAX
MUL RAX, RAX, 2

Mientras que la opción lenta hace:
MOV RAX, [i]
MUL RAX, RAX, 2
MOV RBX, [i]
MUL RAX, RAX, RBX

En el primer caso, se esta haciendo una única llamada a [i] (traer el valor de i desde memoria), mientras que en el segundo, se trae el valor de [i] dos veces. Incluso si en el segundo fragmento juegas un poco con el orden:
MOV RBX [i]
MUL RAX, RBX, 2
MUL RAX, RAX, RBX

Aunque ahora solo usas una llamada a [i], sigues utilizando dos registros. Lo que significa que tienes que guardar el contenido de dichos registros antes en la pila, lo cual también te lleva tiempo.

No me he puesto a mirar en serio la verdad, pero por lo que me conozco de la JVM (basicamente mi trabajo), apostaria dinero a que viene por ahi

O

¿Porque Java es una puta mierda de lenguaje?

O

#49 Java es lento, lento como el solo. Y que tengas que declarar una clase para hacer un puto hola mundo lo convierte automáticamente en basura

D

Lo gracioso, o no tanto, es como el programa simplemente compilado en C puede ir 5 veces más rapido, y sin tener que cargar una maquina virtual ni implementar un jit.

pip

#40 viendo el assembly monstruoso que genera el JIT para esa chorrada (ver respuesta de stackoverflow) te quedas corto con 5 veces.
En el assembly del C para esa operación serán 2 o 3 opcodes.

pip

#40 En C en ambos casos se generan los siguientes opcodes de 80x86 (gcc 8 con -O3 -m64)

imul edi, edi
lea eax, [rdi+rdi]


Punto final.

D

Nadie dice nada del PUTO AMO que da la respuesta en stackoverflow ?

D

java como plataforma o como lenguaje?

D

# su gusto está fuera de duda...salvo por esa manía de repudiar a Charlize Theron...por lo demás de acuerdo en todo.

x

¿Nadie pregunta porqué multiplicar por 2 cuando puedes shiftar un cero por la derecha y ser más eficiente?

garuse

El problema viene cuando el servidor de turno (tomcat, ihs, was) empieza a devorar recursos.

Entonces si dices, f*ck java x''DDDD

kucho

yo diria que porque multiplicar 2i por i es mas lento que i*i y desplazar un bit a la izquierda.

R

#23 No, java no usa el byte shift para esa multiplicación. Todo se resume a que en (2 * i) * i se lee el valor i dos veces, mientras que en 2 * (i * i) solo hace falta leer i una vez.

D

Probablemente al factorizar la multiplicación, el JIT optimice mejor el desenroscado del bucle en el bytecode al tener un stack separado que no necesita preservar.

a

Llevo años pensando que en informática se estudia muy poco acerca del funcionamiento interno de los lenguajes de programación, y me parece preocupante la gran sorpresa que este problema supone, ya que es solo la punta del iceberg de un problema de verdad importante.
Estudio ingeniería de obras públicas y mis conocimientos de programación son ridículos, puedo programar más o menos bien en Fortran90, y un poco en C, pero tanto si hago desde una hoja de excell hasta un programa propio, ensayo primero la fórmula que vaya a implementar en el orden exacto que el programa siga (incluyendo subrutinas, como una raíz cuadrada).
Es importante ya que una simple operación como (a-b)/c, por ejemplo, puede dar un resultado muy distinto de (a/c) - (b/c), debido a la propagación del error de máquina. Esto sucede con mucha frecuencia, entre ciertos rangos de números según cada situación pueden darse facilmente errores de un 5%, y con rangos de operaciones muy concretas, el error será abismal.
Entiendo que esto se estudie a fondo solo para trabajar con bases de datos muy grandes o con cálculos que duren minutos o horas en un ordenador, pero debería darse un poco más cuando se estudian los lenguajes de programación para saber que el problema está ahí.
Dejo un ejemplo de ecuación problemática, puede probarse con la típica calculadora que se usa en la secundaria:
(10^60 )·[(a+x) - (a-x)]
a=1
x=10^-50
Esta operación con esos valores dará como resultado = 0 en una calculadora, en una hoja de cálculo, en java, y en casi cualquier otro lenguaje de programación, a pesar de que la solución analítica es 2·10^10. Me parece un problema importante que no se insista más en esto, luego todos a decir que el lenguaje es una mierda, mientras se programa como se programa, dando palos de ciego con respecto a las matemáticas.

D

#93 No se, creo que te estás liando un poco.
Lo que aquí se está exponiendo es la ligera mejora de rendimiento que supone factorizar la multiplicación del ejemplo propuesto dentro de un bucle en Java. Lo cual se debe probablemente a una mayor optimización del bytecode por parte del JIT al hacer el desenroscado del bucle (loop unrolling) en el primer caso, quizá por tener un stack separado como resultado de dicha factorización y no tener que hacer tantas llamadas a stack para conservar los resultados intermedios que generaría 2 * i * i

a

#99 Yo creo que no me he liado...
Yo he entendido perfectamente la mejora de rendimiento que se expone, pero ahora te pregunto, si cambiasemos el rango de esa ecuación, ¿podría esta mejora de rendimiento afectar al resultado? ¿Confiarías en el resultado de esa sencillísima fórmula?

1 2