Thursday, April 05, 2007

ruby ช้า

ใน codenone คุณสุกรีตั้งโจทย์ Mandelbrot Set ไว้
แน่นอนเมื่อตั้งตัวเป็นผู้สนับสนุน ruby แล้ว
ก็ต้องทดลอง implement ด้วย ruby ดู (haskell เข้าคิวอยู่)

เริ่มแรกสุด ลอง implement algorithm โดยใช้ Datatype ที่มากับ ruby
require 'complex'
def is_mandel(z)
max = 30
cnt = 0
c = z
while (z.abs < 2 && cnt < max)
z = z ** 2 + c
cnt += 1
end
cnt == max ? 0 : cnt
end

สั้นดี ได้ใจความ
ทดลอง run ด้วย loop นี้
def bm()
step = 0.005
x = 0.0
while x < 1.0
y = 0.0
while y < 1.0
is_mandel(Complex.new(x,y))
y += step
end
x += step
end
end

ผลออกมาเกินห้ามใจ
นี่ขนาดคำนวณ แค่ 40000 จุด (200x200 pixel)

user system total real
complex 23.180000 0.260000 23.440000 ( 26.981269)


ปรับไปใช้ algorithm ใน wikipedia
def is_mandel2(x,y)
x0 = x
y0 = y
x2 = x*x
y2 = y*y

cnt = 0
max = 30

while (x2 + y2 < 4 && cnt < max)
y = 2*x*y + y0
x = x2 - y2 + x0

x2 = x*x
y2 = y*y

cnt += 1
end
cnt == max ? 0 : cnt
end


ผลลัพท์ ดีขึ้นหน่อย ดีกว่าเกือบ 4 เท่า
แต่ก็ยังช้าอยู่ดี

user system total real
wikipedia 5.440000 0.080000 5.520000 ( 6.913239)


สุดท้ายก็เปลี่ยนไปใช้ rubyinline
เพื่อจะเห็นแสงสว่างที่ปลายอุโมงค์บ้าง
inline do |builder|
builder.c "
int is_mandel3(double x, double y) {
double x0 = x;
double y0 = y;
double x2 = x * x;
double y2 = y * y;
int cnt = 0;
int max = 30;
while (x2 + y2 < 4 && cnt < max) {
y = 2*x*y + y0;
x = x2 - y2 + x0;
x2 = x*x;
y2 = y*y;
cnt++;
}
return cnt == max ? 0 : cnt;
}"

end

ผลลัพท์ที่ได้ ก็อย่างที่ทุกคนคงคาดไว้

user system total real
inline 0.220000 0.000000 0.220000 ( 0.257189)


Put the right man on the right job.
ภาษาก็เหมือนกัน

Related link from Roti

อำนาจ

รัฐมนตรี ICT คนนี้ใช้ได้เหมือนกันนะ
ตรงที่ทำให้คน IT หลายคน ไดัสัมผัสกับ "อำนาจนิยม"

สิ่งที่พวกเราซึ่งเป็นชนชั้นกลางเจอ ก็อยู่ในขั้นแค่ "รำคาญ" ที่ไม่ได้ดู "ความบันเทิง"
ซึ่งเทียบไม่ได้กับ สิ่งที่กลุ่มคนชั้นล่างได้พบเจอ
ไม่ว่า จะเป็น คนมุสลิมในสามจังหวัดชายแดนภาคใต้
ที่เจอประเด็นเรื่อง รัฐหรือผู้เป็นตัวแทนของรัฐ ไม่มีความเคารพในความแตกต่างของ ความเชื่อ,ศาสนา
หรือ ชาวบ้านที่อาศัยแม่น้ำมูล เป็นแหล่งจับปลา ที่โดนคุกคาม โดยเชื่อนปากมูล ในแบบที่ต้องเปลี่ยนวิถีชีวิตไปเลย
หรือ ชนกลุ่มน้อยที่โดนเพิกถอนบัตรประชาชนแบบเหวี่ยงแห

พูดอย่างนี้ไม่ได้แปลว่าต้อง ปลง กับ สถานะการณ์ตัวเอง (พวก IT)
เพราะเมื่อเจอการใช้อำนาจ ก็ควรจะต้องรวมตัวต่อต้านอำนาจ

Related link from Roti

Wednesday, April 04, 2007

Autism -> Engineering

Autism ใน longdo แปลว่า ความผิดปกติทางการสื่อสารและอารมณ์

มีลูกแล้ว ความสนใจในเรื่องของ Gene เรื่องของ เด็ก ก็เพิ่มสูงขึ้น
วันนี้อ่านเจอ สมมติฐานของ Baron-Conhen เรื่อง Autism-Engineer Hypothesis.
สมมติฐานนี้มีประมาณว่า
พ่อที่เป็นเป็น engineering ถ้าเลือกแต่งงานกับผู้หญิงในแบบ assortative mating
(assortative -> แต่งงานกับคนที่มีคุณสมบัติเหมือนตัวเอง)
มีโอกาสที่ลูกจะได้ gene ที่มีคุณสมบัติเด่นใน systemisers เบิ้ลจากพ่อและแม่
จนก้าวไปสู่บริเวณที่เรียกว่า Autism

ดูตาราง


ไม่ต้องตกใจ สมมติฐานก็คือสมมติฐาน
(โชคดีที่เราไม่ได้แต่งงานกับสายอาชีพ Engineer)

Link
Two new theories of autism: hyper-systemising and assortative mating
(หน้า 4)

Related link from Roti

Tuesday, April 03, 2007

SVN Branching and Merging

ใช้ version control มานานแล้ว
แต่ยังไม่เคยได้ทำ branch & merge operation สักที
หลักๆก็ใช้อยู่แค่ trunk เส้นเดียว
ไม่เคยสร้าง branches ให้ปวดหัว
(ไม่สร้าง branches ก็ปวดหัวไปอีกแบบ)

ปกติในการใช้ version control,
เราสามารถแบ่งลักษณะการใช้ออกเป็น 3 กลุ่ม ตามลักษณะการใช้ branches ได้ดังนี้

พวกที่ 1 ไม่ใช้ branches เลย มีแต่ trunk อย่างเดียว
(บริษัทผม จัดอยู่ในกลุ่มนี้)

พวกที่ 2 พวกนี้สุดโต่งไปอีกด้านหนึ่งก็คือ ใช้แต่ branches เป็นหลัก
trunk เก็บเฉพาะ code ที่ verify ว่า stable แล้วเท่านั้น
ในพวกนี้ เวลาใครจะทำอะไรกับ code ไม่ว่าจะ bug ตัวจิ๊บจ๊อย ก็ต้องสร้าง branch ออกไป
เมื่อเสร็จแล้วจึงจะ merge เข้า trunk

พวกที่ 3 เป็นพวกผสมระหว่าง 1 และ 2 นั่นคือ
การเปลี่ยนแปลงเล็กๆน้อยๆ ก็ใช้ trunk ไป
แต่ถ้าเปลี่ยนเยอะหน่อยก็ใช้ branches

ปัจจุบัน ปัญหาที่ผมเจอก็คือ
เนื่องจาก methodology ที่ผมใช้พัฒนา software ในปัจจุบัน
ใช้เทคนิคแบบ Agile ในการพัฒนา (ทำไปคิดไป)
ซึ่งพอถึงจุดหนึ่ง มันจะเกิด refactor ขนานใหญ่ขึ้น
ก็เลยหลีกเลี่ยงไม่ได้ที่จะต้องทำ branches เพื่อแยกไป refactor ต่างหาก
(แยกไปลองผิดลองถูกต่างหาก จะได้ไม่กระทบคนอื่นเขา)

ใน svn, เวลาเราจะทำ branches
เราสามารถทำได้ง่ายๆ ดังนี้
  • สร้าง directory ที่จะใช้เก็บ branches ของเรา
    มาตรฐานแบบไม่เป็นทางการของ svn กำหนดว่า directory branches ให้เราอยู่แล้ว
    ดังนี้เราก็เลือกสร้าง folder ใต้ directory นี้
    ความยากในขั้นนี้ก็คือการตั้งชื่อ folder

    สมมติเราต้องการสร้าง folder mybranche-1 ก็ให้ใช้คำสั่งนี้

    svn mkdir http://hostname/svn/yourproject/branches/mybranche-1

  • ใช้คำสั่ง copy เพื่อ copy จาก trunk ไปยัง folder ที่เราสร้าง

    svn copy http://hostname/svn/yourproject/trunk \
    http://hostname/svn/yourproject/branches/mybranche-1


แค่นี้ ก็ได้ branche เส้นใหม่ ให้เราได้ลองยำเล่นสมใจแล้ว

ความยากขั้นถัดไป ก็คือการ merge
โดยการ merge จะเกิดได้ 2 กรณี
  • กรณีแรก เราทำ code เสร็จไว, ต้องการ commit change กลับเข้าไปยัง trunk
    การ merge ก็จะเกิดใน ทิศทางจาก branche มายัง trunk
  • กรณีที่สอง เราแก้ไข branch นานมาก จน trunk เปลี่ยนไปเยอะแล้ว,
    ถ้าเกิดเหตุการณ์แบบนี้ เราก็ควรจะ merge การเปลี่ยนแปลงจาก trunk ไปยัง branche เป็นระยะๆ
    เพื่อลดความแตกต่างระหว่าง code ลง


ข้อด้อยของ svn ก็คือ มันไม่มี feature ที่ช่วยจำว่า เรา merge อะไรไแล้วบ้าง
ดังนั้นจึงมีโอกาสที่เราจะ merge ซ้ำซ้อนลงไปได้
best practice ก็คือ ในการ commit การ merge แต่ละครั้ง
ให้เขียน log message ให้ชัดเจนว่า เป็นการ merge จาก revision ไหนถึงไหน
เพื่อจะได้ใช้เป็นข้อมูลเตือนความจำ

ลองดูตัวอย่างการใช้คำสั่ง merge จาก branch ไปยัง trunk
สมมติเรามีเส้นทางของ version เราดังนี้

#trunk# --- revision 149 ------- .... ------- >
\
\ branches
\
+ revision 150 ----- .... ----- revision 159 >


ขั้นตอนการ merge กลับ, เราจะใช้คำสั่ง svn merge เข้ามาช่วย
โดยเราจะสั่งคำสั่งดังนี้

ย้าย current directory ไปยัง working copy ของ trunk
แล้วทำการ update code ให้เป็น code ล่าสุดก่อน

$ cd $WORKING_COPY_OF_MAIN_TRUNK
$ svn update


trick ของการใช้ merge ก็คือ ประเด็นว่าเราจะต้องหาเลข revision เริ่มต้นให้ได้ก่อน (ในที่นี้คือ 150)
เพราะส่วนใหญ่มักจะลืมไม่ได้จดไว้
คำสั่งที่ช่วยหาเลขนี้ก็คือ

svn log -stop-on-copy

โดยมันจะ report log ไปจนถึง จุดที่เกิดการทำ branches (ใน svn การทำ branches คือการ copy)

เมื่อได้เลข revision มาแล้ว ก็สั่ง merge ส่วนเปลี่ยนแปลงที่เกิดขึ้นระหว่าง revision 150 ถึง 159 ใน branches
กับ working copy ของ trunk
โดยเริ่มแรกให้ใส่ parameter --dry-run เพื่อตรวจสอบความถูกต้องก่อน

$ svn merge --dry-run -r 150:159 http://domain/svn/branches/your_branches_name


ซึ่งหลังจากเกิดการ merge แล้ว,
เราก็ต้องตรวจ working copy ของเรา
ว่ามีอะไรผิดผลาดไหม เช่นพวก conflict
พอมั่นใจว่าถูกหมด ก็สั่ง commit ตามปกติ

ส่วนการ merge จาก trunk ไปยัง branch ก็ทำแบบเดียวกัน
เพียงแต่กลับทิศทางกัน

Related link from Roti

Monday, April 02, 2007

Expertise


Research on the acquisition of expertise has shown that
(a) it takes a long time,
(b) it takes intense, focused effort
(c) it can not be taught by direct tuition.

One of the most widely replicated findings in all domains studied is that it
takes at least 10 years to reach expert level.


ที่มา
The Acquisition of Expertise in Software Engineering Education

Related link from Roti