Ah... entendí a qué se refiere. No había entendido qué cosas había que comparar.... el algoritmo quick sort no tiene dos formas de implementación, quicksort e in-place......
Desde el principio, lo que cuestioné fue que se escribieran y se ofrecieran a los usuarios de IA quickSortGPT() y quickSort() del código de arriba (ambos son código generado por GPT), donde la fusión de arrays ya está incorporada.
Incluso ahora, cuando intento trabajar con desarrolladores de 40 o 50 años, a veces me desespera que haya personas que quieran desarrollar de la misma forma que se hacía hace décadas, uff. Personalmente, creo que sería una sociedad más sana si, como en Japón, los jóvenes pudieran entrar a empleos formales en lugar de trabajos de medio tiempo o no regulares, y las personas mayores se concentraran más en trabajos temporales por día. En Corea, la distribución del ingreso laboral está funcionando como una pirámide invertida, así que cada vez se vuelve más fuerte eso de quitarle la escalera a los que vienen detrás.
> Las plataformas de enfermería revisan el historial crediticio de las enfermeras a través de corredores de datos, y cuanto más endeudadas están, menor salario les ofrecen.
Lo ejecuté yo mismo y tiende a ser un poco más lento, pero no creo que llegue a ser 2 veces más lento.
function quickSortInPlace(arr, left = 0, right = arr.length - 1) {
if (left >= right) return;
const pivotIndex = partition(arr, left, right);
quickSortInPlace(arr, left, pivotIndex - 1);
quickSortInPlace(arr, pivotIndex + 1, right);
}
function partition(arr, left, right) {
const pivot = arr[right];
let i = left;
for (let j = left; j < right; j++) {
if (arr[j] < pivot) {
[arr[i], arr[j]] = [arr[j], arr[i]];
i++;
}
}
[arr[i], arr[right]] = [arr[right], arr[i]];
return i;
}
function quickSort(arr) {
if (arr.length <= 1) return arr;
const pivot = arr[arr.length - 1];
const left = [];
const right = [];
for (let i = 0; i < arr.length - 1; i++) {
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return [...quickSort(left), pivot, ...quickSort(right)];
}
// =============
function quickSortGPT(arr) {
if (!Array.isArray(arr)) {
throw new TypeError('quickSort expects an array');
}
if (arr.length <= 1) return [...arr];
const pivot = arr[Math.floor(arr.length / 2)];
const left = [];
const equal = [];
const right = [];
for (const el of arr) {
if (el < pivot) left.push(el);
else if (el > pivot) right.push(el);
else equal.push(el);
}
return [...quickSortGPT(left), ...equal, ...quickSortGPT(right)];
}
function quickSortInPlaceGPT(arr) {
if (!Array.isArray(arr)) {
throw new TypeError('quickSortInPlace expects an array');
}
const stack = [[0, arr.length - 1]];
while (stack.length) {
const [lo, hi] = stack.pop();
if (lo >= hi) continue;
const pivotIndex = partitionGPT(arr, lo, hi);
// Eliminación de recursión de cola: primero apilar la partición más grande
if (pivotIndex - 1 - lo > hi - (pivotIndex + 1)) {
stack.push([lo, pivotIndex - 1]);
stack.push([pivotIndex + 1, hi]);
} else {
stack.push([pivotIndex + 1, hi]);
stack.push([lo, pivotIndex - 1]);
}
}
return arr;
}
function medianOfThreeGPT(a, b, c) {
return (a - b) * (c - a) >= 0 ? a
: (b - a) * (c - b) >= 0 ? b
: c;
}
function partitionGPT(arr, lo, hi) {
const mid = lo + ((hi - lo) >> 1);
const pivotValue = medianOfThreeGPT(arr[lo], arr[mid], arr[hi]);
while (true) {
while (arr[lo] < pivotValue) lo++;
while (arr[hi] > pivotValue) hi--;
if (lo >= hi) return hi;
[arr[lo], arr[hi]] = [arr[hi], arr[lo]];
lo++;
hi--;
}
}
function testQuicksort(qs, qsp) {
const repeat = 100;
const arrLength = 100000;
const unsortedArray = new Array();
for (let i = 0; i < arrLength; i++)
unsortedArray.push(Math.round(Math.random() * arrLength));
let sorted = [];
const qb = performance.now();
for (let i = 0; i < repeat; i++)
sorted = qs(unsortedArray);
const qe = performance.now();
const rqb = performance.now();
for (let i = 0; i < repeat; i++) {
let copied = [...unsortedArray];
qsp(copied);
}
const rqe = performance.now();
// hasta 2 decimales
const p1 = ((qe - qb) / repeat).toFixed(2);
const p2 = ((rqe - rqb) / repeat).toFixed(2);
console.log(`Quicksort: ${p1} ms, In-place: ${p2} ms`);
}
function main() {
const useGPT = process.argv.includes('--gpt');
console.log(`Using ${useGPT ? 'GPT' : 'geekNews'} quicksort implementation.`);
if (useGPT) {
testQuicksort(quickSortGPT, quickSortInPlaceGPT);
} else {
testQuicksort(quickSort, quickSortInPlace);
}
}
main();
===
node q.js
Using geekNews quicksort implementation.
Quicksort: 29.55 ms, In-place: 9.94 ms
node q.js
Using geekNews quicksort implementation.
Quicksort: 28.42 ms, In-place: 9.07 ms
node q.js
Using geekNews quicksort implementation.
Quicksort: 26.91 ms, In-place: 9.15 ms
node q.js --gpt
Using GPT quicksort implementation.
Quicksort: 28.73 ms, In-place: 9.22 ms
node q.js --gpt
Using GPT quicksort implementation.
Quicksort: 26.87 ms, In-place: 9.22 ms
node q.js --gpt
Using GPT quicksort implementation.
Quicksort: 27.97 ms, In-place: 9.30 ms
node --version
v22.14.0
bun q.js
Using geekNews quicksort implementation.
Quicksort: 32.05 ms, In-place: 17.39 ms
bun q.js
Using geekNews quicksort implementation.
Quicksort: 30.97 ms, In-place: 17.82 ms
bun q.js
Using geekNews quicksort implementation.
Quicksort: 29.73 ms, In-place: 16.14 ms
bun q.js --gpt
Using GPT quicksort implementation.
Quicksort: 30.61 ms, In-place: 12.63 ms
bun q.js --gpt
Using GPT quicksort implementation.
Quicksort: 31.09 ms, In-place: 12.76 ms
bun q.js --gpt
Using GPT quicksort implementation.
Quicksort: 33.24 ms, In-place: 12.75 ms
bun --version
1.2.14
deno q.js
Using geekNews quicksort implementation.
Quicksort: 32.30 ms, In-place: 6.79 ms
deno q.js
Using geekNews quicksort implementation.
Quicksort: 26.79 ms, In-place: 6.86 ms
deno q.js
Using geekNews quicksort implementation.
Quicksort: 26.09 ms, In-place: 6.85 ms
deno q.js --gpt
Using GPT quicksort implementation.
Quicksort: 27.18 ms, In-place: 7.92 ms
deno q.js --gpt
Using GPT quicksort implementation.
Quicksort: 25.34 ms, In-place: 8.12 ms
deno q.js --gpt
Using GPT quicksort implementation.
Quicksort: 25.39 ms, In-place: 8.09 ms
deno --version
deno 2.3.3 (stable, release, x86_64-pc-windows-msvc)
v8 13.7.152.6-rusty
typescript 5.8.3
Así como "después de ahogado el niño, tapan el pozo" no significa que no debamos prepararnos para el futuro,
creo que "no reinventes la rueda" tampoco significa que no debamos invertir tiempo en obtener comprensión.
Si se recorta el contexto en el que surgieron esas palabras, se distorsiona su verdadero significado.
Cuando termino repitiendo varias veces para resolver el mismo problema, me salgo del tamaño de la ventana de contexto y ya me ha pasado varias veces que la IA se rompe en esos casos; me da curiosidad saber cómo lo manejan los demás.
Yo, cuando después de varios intentos empieza a comportarse de forma tonta, cambio de modelo y abro una nueva ventana de prompt.
Es una experiencia reciente, pero hace poco hice mi propia rueda muy especial.
Construir una app de 1000 páginas en Nuxt tomaba 7 minutos,
pero al renunciar a algunas automatizaciones y reescribirla, logré una compilación de 20 segundos.
Normalmente no suelo dejar comentarios, pero la razón por la que comenté justamente en este artículo es que coincido bastante con lo que piensa el autor. No es que la IA o los LLM sean lo importante, sino que, sin importar qué clase de entorno llegue, creo que como desarrollador debo estar preparado.
Por las características del código fuente con el que se entrenan, los LLM suelen ofrecer datos cercanos al promedio de los datos en línea repartidos por todo el mundo. (El caso anterior de quicksort en js lo demuestra). Por eso, normalmente los uso mucho para preguntar si, desde el punto de vista de ideas/diseño, algo coincide o se desvía en cierta medida de una perspectiva general, o para consultar cosas sobre las que hasta ahora era ambiguo a quién preguntar.
Además, no estoy muy seguro de qué sentido tiene seguir conversando más sobre esto.
Si desde el principio la postura era que el código que genera la IA puede tener ciertos riesgos, así que conviene refinarlo bien y usarlo de manera adecuada, entonces parecería suficiente con que se explicara en qué aspecto el texto del autor refleja un sesgo en su forma de pensar. Incluso en el resumen aparece una idea similar: "puede proporcionar rápidamente código scaffold/borrador sin contexto, pero el diseño completo y el ajuste fino siguen siendo responsabilidad de los desarrolladores humanos".
Básicamente, se puede considerar que es un código que no tiene ninguna sensibilidad respecto a la carga de crear, operar y fusionar colecciones. En el caso de C++, ya hace unos 10 años surgieron propuestas/implementaciones relacionadas con el Move Constructor, y estar siempre muy alerta respecto al costo de la copia de memoria es de lo más básico. quick sort, por su mecanismo, es un algoritmo que puede fijar el índice de todos los valores, y es mejor que cada campo permita acceso aleatorio.
Incluso sin optimizaciones maniáticas, con solo aplicar lo anterior ya hay una diferencia de rendimiento de más del doble frente al método del enlace que compartiste.
Por supuesto, la comparación debe hacerse entre el rendimiento de las dos funciones
quickSort()yquickSortInPlace()........Ah... entendí a qué se refiere. No había entendido qué cosas había que comparar.... el algoritmo quick sort no tiene dos formas de implementación,
quicksortein-place......Desde el principio, lo que cuestioné fue que se escribieran y se ofrecieran a los usuarios de IA
quickSortGPT()yquickSort()del código de arriba (ambos son código generado por GPT), donde la fusión de arrays ya está incorporada.¿Compartir un resultado donde se ve una diferencia de más del doble, incluso de 3 a 4 veces, y luego decir que no parece llegar al doble?
Incluso ahora, cuando intento trabajar con desarrolladores de 40 o 50 años, a veces me desespera que haya personas que quieran desarrollar de la misma forma que se hacía hace décadas, uff. Personalmente, creo que sería una sociedad más sana si, como en Japón, los jóvenes pudieran entrar a empleos formales en lugar de trabajos de medio tiempo o no regulares, y las personas mayores se concentraran más en trabajos temporales por día. En Corea, la distribución del ingreso laboral está funcionando como una pirámide invertida, así que cada vez se vuelve más fuerte eso de quitarle la escalera a los que vienen detrás.
> Las plataformas de enfermería revisan el historial crediticio de las enfermeras a través de corredores de datos, y cuanto más endeudadas están, menor salario les ofrecen.
¿Cómo se proporciona esta información?
Lo ejecuté yo mismo y tiende a ser un poco más lento, pero no creo que llegue a ser 2 veces más lento.
===
node q.js
Using geekNews quicksort implementation.
Quicksort: 29.55 ms, In-place: 9.94 ms
node q.js
Using geekNews quicksort implementation.
Quicksort: 28.42 ms, In-place: 9.07 ms
node q.js
Using geekNews quicksort implementation.
Quicksort: 26.91 ms, In-place: 9.15 ms
node q.js --gpt
Using GPT quicksort implementation.
Quicksort: 28.73 ms, In-place: 9.22 ms
node q.js --gpt
Using GPT quicksort implementation.
Quicksort: 26.87 ms, In-place: 9.22 ms
node q.js --gpt
Using GPT quicksort implementation.
Quicksort: 27.97 ms, In-place: 9.30 ms
node --version
v22.14.0
bun q.js
Using geekNews quicksort implementation.
Quicksort: 32.05 ms, In-place: 17.39 ms
bun q.js
Using geekNews quicksort implementation.
Quicksort: 30.97 ms, In-place: 17.82 ms
bun q.js
Using geekNews quicksort implementation.
Quicksort: 29.73 ms, In-place: 16.14 ms
bun q.js --gpt
Using GPT quicksort implementation.
Quicksort: 30.61 ms, In-place: 12.63 ms
bun q.js --gpt
Using GPT quicksort implementation.
Quicksort: 31.09 ms, In-place: 12.76 ms
bun q.js --gpt
Using GPT quicksort implementation.
Quicksort: 33.24 ms, In-place: 12.75 ms
bun --version
1.2.14
deno q.js
Using geekNews quicksort implementation.
Quicksort: 32.30 ms, In-place: 6.79 ms
deno q.js
Using geekNews quicksort implementation.
Quicksort: 26.79 ms, In-place: 6.86 ms
deno q.js
Using geekNews quicksort implementation.
Quicksort: 26.09 ms, In-place: 6.85 ms
deno q.js --gpt
Using GPT quicksort implementation.
Quicksort: 27.18 ms, In-place: 7.92 ms
deno q.js --gpt
Using GPT quicksort implementation.
Quicksort: 25.34 ms, In-place: 8.12 ms
deno q.js --gpt
Using GPT quicksort implementation.
Quicksort: 25.39 ms, In-place: 8.09 ms
deno --version
deno 2.3.3 (stable, release, x86_64-pc-windows-msvc)
v8 13.7.152.6-rusty
typescript 5.8.3
....¿eh?
Antes de la presentación hubo una introducción del patrocinio de Google y Facebook.
Así como "después de ahogado el niño, tapan el pozo" no significa que no debamos prepararnos para el futuro,
creo que "no reinventes la rueda" tampoco significa que no debamos invertir tiempo en obtener comprensión.
Si se recorta el contexto en el que surgieron esas palabras, se distorsiona su verdadero significado.
Creo que la mayor especialidad de Estados Unidos es el dólar.
Cuando termino repitiendo varias veces para resolver el mismo problema, me salgo del tamaño de la ventana de contexto y ya me ha pasado varias veces que la IA se rompe en esos casos; me da curiosidad saber cómo lo manejan los demás.
Yo, cuando después de varios intentos empieza a comportarse de forma tonta, cambio de modelo y abro una nueva ventana de prompt.
Es una experiencia reciente, pero hace poco hice mi propia rueda muy especial.
Construir una app de 1000 páginas en Nuxt tomaba 7 minutos,
pero al renunciar a algunas automatizaciones y reescribirla, logré una compilación de 20 segundos.
OSSU Open Source Society University - estudiar Computer Science por cuenta propia
Parece que lo presentaron en los inicios de GeekNews. Desde entonces se han agregado bastantes cosas.
¡Gracias por tu respuesta!
La segunda
quickSortInPlace()que adjuntaste también es una implementación lenta.Prueba ejecutar el código de abajo.
function quickSortInPlace(arr, left = 0, right = arr.length - 1) {
if (left >= right) return;
const pivotIndex = partition(arr, left, right);
quickSortInPlace(arr, left, pivotIndex - 1);
quickSortInPlace(arr, pivotIndex + 1, right);
}
function partition(arr, left, right) {
const pivot = arr[right];
let i = left;
for (let j = left; j < right; j++) {
if (arr[j] < pivot) {
[arr[i], arr[j]] = [arr[j], arr[i]];
i++;
}
}
[arr[i], arr[right]] = [arr[right], arr[i]];
return i;
}
function quickSort(arr) {
if (arr.length <= 1) return arr;
const pivot = arr[arr.length - 1];
const left = [];
const right = [];
for (let i = 0; i < arr.length - 1; i++) {
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return [...quickSort(left), pivot, ...quickSort(right)];
}
const repeat = 100;
const arrLength = 10000;
const unsortedArray = new Array<number>();
for(let i = 0; i < arrLength; i++)
unsortedArray.push(Math.round(Math.random() * arrLength));
let sorted: Array<number>;
const qb = performance.now();
for(let i = 0; i < repeat; i++)
sorted = quickSort(unsortedArray);
const qe = performance.now();
const rqb = performance.now();
for(let i = 0; i < repeat; i++) {
let copied = [...unsortedArray];
quickSortInPlace(copied);
}
const rqe = performance.now();
console.log(
q: ${qe - qb} ::: rq: ${rqe - rqb});Es un texto que transmite una gran profundidad. Como era de esperarse de a16z.
Normalmente no suelo dejar comentarios, pero la razón por la que comenté justamente en este artículo es que coincido bastante con lo que piensa el autor. No es que la IA o los LLM sean lo importante, sino que, sin importar qué clase de entorno llegue, creo que como desarrollador debo estar preparado.
Por las características del código fuente con el que se entrenan, los LLM suelen ofrecer datos cercanos al promedio de los datos en línea repartidos por todo el mundo. (El caso anterior de quicksort en js lo demuestra). Por eso, normalmente los uso mucho para preguntar si, desde el punto de vista de ideas/diseño, algo coincide o se desvía en cierta medida de una perspectiva general, o para consultar cosas sobre las que hasta ahora era ambiguo a quién preguntar.
Además, no estoy muy seguro de qué sentido tiene seguir conversando más sobre esto.
Si desde el principio la postura era que el código que genera la IA puede tener ciertos riesgos, así que conviene refinarlo bien y usarlo de manera adecuada, entonces parecería suficiente con que se explicara en qué aspecto el texto del autor refleja un sesgo en su forma de pensar. Incluso en el resumen aparece una idea similar: "puede proporcionar rápidamente código scaffold/borrador sin contexto, pero el diseño completo y el ajuste fino siguen siendo responsabilidad de los desarrolladores humanos".
Básicamente, se puede considerar que es un código que no tiene ninguna sensibilidad respecto a la carga de crear, operar y fusionar colecciones. En el caso de C++, ya hace unos 10 años surgieron propuestas/implementaciones relacionadas con el Move Constructor, y estar siempre muy alerta respecto al costo de la copia de memoria es de lo más básico.
quick sort, por su mecanismo, es un algoritmo que puede fijar el índice de todos los valores, y es mejor que cada campo permita acceso aleatorio.Incluso sin optimizaciones maniáticas, con solo aplicar lo anterior ya hay una diferencia de rendimiento de más del doble frente al método del enlace que compartiste.
return [...quickSort(left), ...equal, ...quickSort(right)];
Piensa bien en esta parte del código.