NX Lab

Tối ưu hiệu năng script lớn: gom thao tác, hoãn cập nhật và tránh gọi API lặp trong vòng lặp

#Python#Hiệu năng1 lượt xem

  1. Quản trị viênQuản trị· 0 điểm

    Câu hỏi ·

    Script tạo 500 feature chạy 20 phút là bình thường nếu mỗi lần tạo bắt NX cập nhật toàn bộ mô hình. Ba cách thường giúp nhất: gom dữ liệu trước, hoãn cập nhật, và cache kết quả gọi API đắt tiền.

    Tối ưu hiệu năng script lớn Tối ưu hiệu năng script lớn

    Các bước thực hiện

    1. Đo trước khi tối ưu. Dùng bộ đếm thời gian của bài trước.
    2. Gom dữ liệu. Đọc thuộc tính một lần, lưu vào biến thay vì gọi lại.
    3. Giảm số lần cập nhật. Dùng Update.Option.Later và gọi DoUpdate một lần.
    4. Cache. Lưu kết quả hàm đắt tiền theo khóa.
    5. Đo lại. So sánh trước/sau.

    Code tham khảo (Python)

    import functools
    import time
    import NXOpen
    
    @functools.lru_cache(maxsize=None)
    def mat_do_theo_vat_lieu(ten):
        """Giả lập hàm đắt tiền (tra bảng, đọc file): chỉ chạy một lần cho mỗi tên."""
        time.sleep(0.05)
        return {"S45C": 7.85e-6, "AL6061": 2.70e-6}.get(ten, 7.85e-6)
    
    def cham_gom(part, so_diem):
        """Cách chậm: mỗi lần tạo điểm đều cập nhật ngay."""
        t0 = time.perf_counter()
        for i in range(so_diem):
            part.Points.CreatePoint(NXOpen.Point3d(i, 0, 0))
        return time.perf_counter() - t0
    
    def nhanh_gom(session, part, so_diem):
        """Cách nhanh hơn: tạo xong cả loạt rồi mới cập nhật một lần."""
        t0 = time.perf_counter()
        mark = session.SetUndoMark(NXOpen.Session.MarkVisibility.Invisible, "Gom diem")
        try:
            for i in range(so_diem):
                part.Points.CreatePoint(NXOpen.Point3d(i, 5, 0))
            session.UpdateManager.DoUpdate(mark)
        finally:
            session.DeleteUndoMark(mark, "Gom diem")
        return time.perf_counter() - t0
    
    def main():
        session = NXOpen.Session.GetSession()
        lw = session.ListingWindow
        lw.Open()
        part = session.Parts.Work
        if part is None:
            return
        lw.WriteLine("Cách 1: %.2f s" % cham_gom(part, 200))
        lw.WriteLine("Cách 2: %.2f s" % nhanh_gom(session, part, 200))
        t0 = time.perf_counter()
        for _ in range(100):
            mat_do_theo_vat_lieu("S45C")
        lw.WriteLine("Tra mật độ 100 lần với cache: %.3f s" % (time.perf_counter() - t0))
    
    if __name__ == "__main__":
        main()
    

    Giải thích code

    • functools.lru_cache lưu kết quả của lần gọi đầu, các lần sau trả ngay, rất hợp cho hàm tra bảng hay đọc file.
    • Hiệu quả của việc hoãn cập nhật tuỳ loại thao tác: với feature phức tạp tác dụng lớn, với điểm đơn giản thì nhỏ.
    • Luôn đo chứ đừng đoán; lần đầu chạy thường chậm hơn các lần sau do NX nạp dữ liệu.

    Lỗi thường gặp

    • Cache lưu theo đối số nên chỉ dùng cho hàm thuần (cùng đầu vào luôn cùng kết quả).
    • Tối ưu sớm làm code khó đọc; chỉ tối ưu chỗ đo được là chậm.

    Code mang tính tham khảo, viết cho NX 12 trở lên (Python journal). Tên menu và một số lớp có thể khác theo phiên bản NX; hãy chạy thử trên bản sao của chi tiết trước khi dùng cho dữ liệu thật.

    Điểm: 0

Trả lời

Đăng nhập để tham gia thảo luận.