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);
// Tail‑recursion elimination: push larger partition first
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();
// ถึงทศนิยม 2 ตำแหน่ง
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
แน่นอนว่า การเปรียบเทียบควรเป็นการเปรียบเทียบประสิทธิภาพของฟังก์ชัน
quickSort()กับquickSortInPlace()ทั้งสองตัว........อา.. ผมเข้าใจแล้วว่าคุณหมายถึงอะไร ดูเหมือนว่าคุณยังไม่เข้าใจว่าควรจะเปรียบเทียบอะไรกับอะไรนี่เอง.... อัลกอริทึม quick sort ไม่ได้มีวิธี implement อยู่สองแบบคือ quicksort กับ in-place นะครับ......
ประเด็นที่ผมวิจารณ์ตั้งแต่แรกคือ การเขียน
quickSortGPT()กับquickSort()ในโค้ดข้างต้นซึ่งมีการรวม Array ไว้ในตัวอยู่แล้ว (ทั้งสองอันเป็นโค้ดที่ GPT สร้างออกมา) แล้วนำไปให้ผู้ใช้ AI ใช้งานนั่นเองก็แชร์ผลลัพธ์ที่ออกมาว่าต่างกันเกิน 2 เท่า ไปจนถึง 3–4 เท่าอยู่แล้ว แต่กลับบอกว่าไม่น่าจะถึง 2 เท่างั้นเหรอ?
แม้แต่ตอนนี้ เวลาต้องทำงานกับนักพัฒนาอายุ 40-50 ปี บางทีก็หงุดหงิดมากเพราะมีคนที่พยายามพัฒนาแบบเดิม ๆ ที่เคยทำกันเมื่อหลายสิบปีก่อน เฮ้อ ส่วนตัวผมคิดว่าเหมือนญี่ปุ่น คือควรทำให้คนหนุ่มสาวได้เข้าทำงานประจำแทนงานพาร์ตไทม์หรืองานไม่ประจำ และให้ผู้สูงอายุไปทำงานพาร์ตไทม์รายวันเป็นหลัก ถึงจะเป็นสังคมที่สุขภาพดีกว่าได้ เกาหลีใต้ตอนนี้กำลังกระจายรายได้จากแรงงานแบบพีระมิดกลับหัว เลยยิ่งมีแต่การถีบบันไดทิ้งรุนแรงขึ้นเรื่อย ๆ
> แพลตฟอร์มพยาบาลตรวจสอบสถานะเครดิตของพยาบาลผ่านนายหน้าข้อมูล และยิ่งมีหนี้มากก็ยิ่งเสนอค่าจ้างที่ต่ำลง
ข้อมูลนี้ถูกจัดหาให้ได้อย่างไร?
ผมลองรันเองแล้ว มีแนวโน้มว่าจะช้ากว่านิดหน่อย แต่ดูเหมือนจะไม่ถึง 2 เท่านะครับ
===
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
....เอ๊ะ?
ก่อนการบรรยาย มีการแนะนำผู้สนับสนุนจาก Google และ Facebook
ผมมองว่า เช่นเดียวกับที่คำว่า "วัวหายแล้วค่อยล้อมคอก" ไม่ได้หมายความว่าไม่ต้องเตรียมพร้อมสำหรับอนาคต
คำว่า "อย่าประดิษฐ์ล้อขึ้นมาใหม่" ก็ไม่ได้หมายความว่าไม่ควรลงทุนเวลาเพื่อให้ได้มาซึ่งความเข้าใจลึกซึ้ง
หากตัดคำพูดเหล่านี้ออกจากบริบทที่มันถูกพูดขึ้นมา ความหมายที่แท้จริงก็จะบิดเบือนไป
ผมคิดว่าสินค้าขึ้นชื่อที่สุดของสหรัฐฯ คือดอลลาร์
พอทำซ้ำหลายรอบเพื่อแก้ปัญหาเดิม ก็จะหลุดเกินขนาดของ context window และผมก็เจอหลายครั้งว่า AI เหมือนพังไปเลย เลยอยากรู้ว่าในกรณีแบบนี้คนอื่นจัดการกันอย่างไร
ส่วนผมถ้าลองหลายครั้งแล้วยังทำตัวเหมือนโง่ ๆ ก็จะเปลี่ยนโมเดลแล้วเปิดหน้าต่างพรอมป์ต์ใหม่
นี่เป็นประสบการณ์ล่าสุดของผมเอง แต่เมื่อไม่นานมานี้ผมได้สร้างวงล้อที่พิเศษมากของตัวเองขึ้นมาอันหนึ่ง
การบิลด์แอปบน Nuxt ที่มี 1000 หน้าเคยใช้เวลา 7 นาที
แต่หลังจากยอมละทิ้งระบบอัตโนมัติบางอย่างแล้วเขียนขึ้นใหม่ ผลลัพธ์คือบิลด์ได้สำเร็จใน 20 วินาที
OSSU Open Source Society University - เรียน Computer Science ด้วยตนเอง
เหมือนว่าเคยแนะนำไว้ตั้งแต่ช่วงแรก ๆ ของ GeekNews แล้วนะครับ ระหว่างนั้นก็มีการเพิ่มเนื้อหาเข้ามาอีกค่อนข้างมาก
ขอบคุณสำหรับคำตอบ!
quickSortInPlace()ตัวที่สองที่แนบมานี่ก็เป็น implementation ที่ช้าเหมือนกันนะครับลองรันโค้ดด้านล่างดูครับ
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});เป็นบทความที่ให้ความรู้สึกถึงมุมมองเชิงลึกจริง ๆ สมกับเป็น a16z
ปกติผมไม่ค่อยเขียนคอมเมนต์เท่าไร แต่เหตุผลที่คอมเมนต์ในบทความนี้เป็นพิเศษก็เพราะผมเห็นด้วยกับความคิดของผู้เขียนอย่างมาก ผมคิดว่าสิ่งสำคัญไม่ใช่ AI หรือ LLM แต่ไม่ว่าสภาพแวดล้อมแบบไหนจะมาถึง ตัว "ผม" ในฐานะนักพัฒนาต้องพร้อมอยู่เสมอ
ด้วยลักษณะของซอร์สที่ใช้ในการฝึก LLM จึงมักให้ข้อมูลที่อยู่ใกล้กับค่าเฉลี่ยของข้อมูลออนไลน์ที่กระจายอยู่ทั่วโลกเป็นหลัก (ก่อนหน้านี้กรณี js quicksort ก็พิสูจน์เรื่องนี้ได้) เพราะฉะนั้นโดยทั่วไปผมจึงใช้มันเพื่อถามว่าในด้านแนวคิด/การออกแบบ สิ่งนั้นสอดคล้องหรือคลาดไปจากมุมมองทั่วไปมากน้อยแค่ไหน หรือใช้ถามเรื่องที่ก่อนหน้านี้ไม่ค่อยแน่ใจว่าจะไปถามที่ไหนดี
ผมไม่ค่อยแน่ใจว่าการคุยต่อไปอีกจะมีความหมายอย่างไร
ตั้งแต่แรกแล้ว ถ้าความเห็นคือโค้ดที่ AI สร้างให้ในตอนแรกอาจมีความเสี่ยงอยู่บ้าง จึงควรขัดเกลาให้ดีและนำไปใช้อย่างเหมาะสม ก็คงพอจะอธิบายได้ว่าบทความของผู้เขียนมีแนวคิดส่วนไหนที่เอนเอียงไปบ้าง เพราะแม้แต่ในบทสรุปก็มีข้อความในทำนองเดียวกันว่า "สามารถสร้าง scaffold/โค้ดร่างที่ไร้บริบทได้อย่างรวดเร็ว แต่การออกแบบและการจูนให้สมบูรณ์ยังเป็นหน้าที่ของนักพัฒนามนุษย์" อยู่เหมือนกัน
โดยพื้นฐานแล้ว นี่ถือเป็นโค้ดที่ไม่เข้าใจภาระของการสร้าง การใช้งาน และการรวม collection เลยแม้แต่น้อย ในกรณีของ C++ นั้น ตั้งแต่ราว 10 ปีก่อนก็มีทั้งข้อเสนอ/การนำ MoveConstructor ไปใช้แล้ว และการระแวดระวังภาระที่เกี่ยวข้องกับการคัดลอกหน่วยความจำก็เป็นพื้นฐานอย่างยิ่งอยู่เสมอ quick sort ตามกลไกของมันเป็นอัลกอริทึมที่สามารถกำหนด index ของค่าทั้งหมดได้ และแต่ละฟิลด์ก็ควรรองรับ random access
ต่อให้ไม่ทำ optimization แบบสุดโต่ง แค่นำสิ่งที่กล่าวมาข้างต้นไปใช้ ก็ได้ประสิทธิภาพต่างจากวิธีในลิงก์ที่คุณให้มาเกิน 2 เท่าแล้ว
return [...quickSort(left), ...equal, ...quickSort(right)];ลองวางโค้ดส่วนนี้ไว้ แล้วคิดดูให้ดี ๆ