[Python] Optimize what needs optimizing?

ปกติแล้ว เวลาผมเขียนโปรแกรมจะถือคตินี้มาตลอด นั่นคือ

Make it done, make it right, and then make it fast.

blog นี้จะมาบอกว่า เราจะ opimize โปรแกรมที่เขียนด้วยภาษา python ได้อย่างไรบ้าง

อย่างแรก ให้ติดตั้ง Python profiler ก่อน คลิก เพื่อดูว่าแต่ละ function ใช้เวลาในการทำงานนานเท่าไหร่

blog นี้ ผมจะสรุปจาก PerformanceTips ละกันครับ

  1. เลือก Data structure ให้เหมาะสม
  2. ใช้ Sorting ของ Python
    อ้างอิงจาก Comparing the well-known sorting algorithm ซึ่งผมเคยเทียบประสิทธิภาพไปแล้วว่า python sorting เร็วกว่าใครเพื่อน นอกจากนั้น Guido van Rossum ยังแนะนำให้ใช้ comparator
  3. String Concatenation
    หลีกเลี่ยง (เอา string ใน list มา concat กัน)

    s = ""
    for substring in list:
        s += substring

    แนะนำ

    s = "".join(list)

    หลีกเลี่ยง

    out = "" + head + prologue + query + tail + ""

    แนะนำ

    out = "%s%s%s%s" % (head, prologue, query, tail)

    แต่จะดูดีและเร็วขึ้นอีก ถ้าเขียนแบบนี้ (โฮก!! หล่อมาก++)

    out = "%(head)s%(prologue)s%(query)s%(tail)s" % locals()
  4. Loops แนะนำให้ใช้ map-function
    หลีกเลี่ยง (แปลง string ใน list เป็น upper case)

    newlist = []
    for word in oldlist:
        newlist.append(word.upper())

    แนะนำ

    newlist = map(str.upper, oldlist)

    หรือ

    newlist = (s.upper() for s in oldlist)
  5. Avoiding dot…
    หลีกเลี่ยงการใช้ method chaining เช่น ‘AbCDe1234′.lower().count(‘a’) เป็นต้น
  6. Local Variable
    Python สามารถ access local variable ได้เร็วกว่า global variable
  7. Initialize dictionary element
    แนะนำให้ตั้งค่าเริ่มต้นให้กับ dictionary

    wdict = {}
    for word in words:
        if word not in wdict:
            wdict[word] = 0
        wdict[word] += 1

    หรือเขียนได้อีกแบบ

    wdict = {}
    for word in words:
        try:
            wdict[word] += 1
        except KeyError:
            wdict[word] = 1
  8. import statement overhead
    ทุกคำสั่ง import จะมี overhead เสมอ และหลีกเลี่ยงการใช้ import ภายใน function เช่น

    def foo():
        import os
        ...
  9. Data aggregation
    หลีกเลี่ยงการใช้ for loop ไปเรียก function
    หลีกเลี่ยง

    import time
    x = 0
    def doit1(i):
        global x
        x = x + i
     
    list = range(100000)
    t = time.time()
    for i in list:
        doit1(i)
     
    print "%.3f" % (time.time()-t)

    แนะนำ

    import time
    x = 0
    def doit2(list):
        global x
        for i in list:
            x = x + i
     
    list = range(100000)
    t = time.time()
    doit2(list)
    print "%.3f" % (time.time()-t)
  10. use xrange instead of range

โอ้ 10 ข้อแหนะ ถ้าทำได้หมดแล้วยังไม่เร็วขึ้น แนะนำให้ใช้ Python Psyco ละครับครับ

One Comment

  1. pamon says:

    “Make it done, make it right, and then make it fast.” ไม่เคยเห็นถือคตินี่เลย เคยเห็นแต่ถือคติ “Make it best in once time.” อย่างเดียวเรย = =

Leave a Reply