2010-06-27 27 views
6

Tôi đang cố gắng sử dụng cụm từ thông dụng để xác định định dạng người dùng đã áp dụng khi nhập dữ liệu vào trong hộp văn bản.
Các biểu thức thông thường như sau:Tại sao các cụm từ thông dụng này thực thi chậm trong Java?

(\\s?[" + alphabet + "]{9,9})+ 

Để xác định liệu đầu vào là một hoặc nhiều chuỗi có độ dài 9 bằng chữ cái nhất định, có thể cách nhau bởi khoảng trắng.

(>[\\w\\s]+\\n[" + alphabet + "\\s]+)+ 

Để kiểm tra xem đầu vào là trong FASTA format

Các biểu thức thông thường chạy chậm khủng khiếp khi kết hợp với . Tại sao điều này?

Tôi nhận thấy điều này có thể là do Java lưu trữ tất cả các kết quả phù hợp (mà tôi không cần tại thời điểm này), nhưng thêm ?: vào mỗi dấu ngoặc đơn sẽ phá vỡ regex. Làm sao nó có thể hoàn thành?

Cảm ơn bạn,

Martin

Sửa 1: tôi đã không thể tạo lại vấn đề này - nó chỉ xảy ra trên một máy tính. Điều này có thể gợi ý điều gì đó sai với thiết lập VM cụ thể đó.
Chúng ta cần một cái gì đó mạnh mẽ hơn, và vì vậy chúng tôi sẽ thực hiện điều này một cách khác nhau. Tôi đã chọn câu trả lời của Joel là câu trả lời đúng, vì tôi tin rằng một số trường hợp đặc biệt trong mẫu có thể là nguyên nhân.

+0

Có bao nhiêu mẫu mà bạn có khả năng đang cố gắng đối sánh với mỗi chuỗi đầu vào? Các mẫu có động hay tĩnh không? –

+0

@ Joel Chỉ có hai mẫu này. Chúng tĩnh. Sử dụng String.matches sẽ gây ra một biên dịch mỗi lần, nhưng ngay cả phù hợp với các mô hình một thời gian rất mất (> 10s cho khoảng 300 ký tự đầu vào) –

+0

bạn có thể xác định "khủng khiếp chậm"? –

Trả lời

0

Nếu bạn có một số mẫu biểu thức chính quy khác nhau được đối sánh với cùng một đầu vào để cố gắng phân loại đầu vào, thì bạn có thể sử dụng trình tạo phân tích từ vựng tốt hơn như JFlex.

Các công cụ phân tích từ vựng và phân tích cú pháp dựa trên Java khác thường được sử dụng trong xây dựng trình biên dịch có thể được tìm thấy được liệt kê here.

+0

Đó là những công cụ hữu ích, cảm ơn! Nhưng tôi chỉ có 2 regex, và điều này rất đơn giản - tôi nghĩ rằng việc sử dụng JFlex và những thứ tương tự sẽ là quá mức cần thiết. –

+0

@Martin - Nghe có vẻ như JFlex hoặc những thứ tương tự sẽ cần nhiều hơn bình thường trong trường hợp này. Tuy nhiên, khi nhìn kỹ hơn các cụm từ thông dụng bạn đang sử dụng, có thể trường hợp của bạn đang phơi bày một số trường hợp thoái hóa trong cách lớp Pattern biên dịch máy phân tích của nó. Nó có thể là giá trị cố gắng JFlex chỉ để xem nếu nó có thể sản xuất một phân tích chặt chẽ hơn cho kịch bản này. –

1

chuỗi.matches() biên dịch regex mỗi khi bạn làm điều đó. Thay vào đó, hãy xem các lớp Pattern/Matcher, cho phép bạn cache các regex được biên dịch trước.

Một điều nữa là sử dụng nhóm regex không bắt nếu bạn không cần kết quả khớp.

+0

Tôi chỉ gọi các trận đấu() một lần, vì vậy điều đó không phải là vấn đề. Các regex hoạt động tốt với đầu vào nhỏ, nhưng chậm chạp một cách khủng khiếp với đầu vào của hơn 200 ký tự. Tôi không thể nhận các nhóm không bắt giữ để làm việc - bạn có thể đưa ra một ví dụ không? –

+0

Việc chuyển sang nhóm không chụp sẽ không cung cấp cho bạn hệ số 1000 cải tiến. Tuy nhiên, đây là cách bạn làm điều đó - đặt?: Sau khi mở ngoặc đơn - ví dụ: (?: \\ s? ["+ Bảng chữ cái +"] {9,9}) + – ddimitrov

1

điều này có thể không giải thích được sự cố cụ thể của bạn. nhưng một khi tôi đi sâu vào việc thực hiện regex của JDK, và tôi đã ngạc nhiên về cách không phức tạp nó được. nó không thực sự xây dựng một máy trạng thái tiến bộ ở mỗi đầu vào char. Tôi cho rằng họ có lý do của họ.

trong trường hợp của bạn, thật dễ dàng để viết một phân tích cú pháp một mình, bằng tay. mọi người lo sợ để làm điều đó, có vẻ như "câm" để tự mã hóa các bước nhỏ này, và mọi người nghĩ rằng các thư viện được thiết lập phải làm một số thủ thuật tuyệt vời để làm tốt hơn các giải pháp được trồng tại nhà. Đo không phải sự thật. trong nhiều trường hợp, nhu cầu của chúng ta khá đơn giản, và nó đơn giản và nhanh hơn cho DIY.

+0

Phương thức Pattern.compile() xây dựng máy trạng thái của dòng con của lớp Pattern.Node. Bạn có nghĩa là nó xây dựng một automaton NFA như trái ngược với DFA? Đó là thiết kế được sử dụng bởi hầu hết các công cụ regex giàu tính năng, tốc độ giao dịch cho các tính năng. Đây là một bài viết giải thích điều này và đề xuất thay thế: http://weblogs.java.net/blog/2006/03/27/faster-java-regex-package – ddimitrov

Các vấn đề liên quan