Tôi muốn biết nếu Nokogiri XPath hoặc phân tích cú pháp CSS hoạt động nhanh hơn với các tệp HTML. Tốc độ khác nhau như thế nào?Phân tích cú pháp XPath hoặc CSS nhanh hơn (đối với Nokogiri trên các tệp HTML)?
Trả lời
Nokogiri không có XPath hoặc CSS phân tích cú pháp. Nó phân tích XML/HTML thành một DOM duy nhất mà sau đó bạn có thể sử dụng cú pháp CSS hoặc XPath để truy vấn.
Bộ chọn CSS được chuyển thành XPath bên trong trước khi yêu cầu libxml2 thực hiện truy vấn. Như vậy (đối với cùng một bộ chọn chính xác) phiên bản XPath sẽ là một phần nhỏ nhanh hơn, vì CSS không cần phải được chuyển đổi thành XPath trước.
Tuy nhiên, câu hỏi của bạn không có câu trả lời chung; nó phụ thuộc vào những gì bạn đang lựa chọn, và XPath của bạn trông như thế nào. Rất có thể, bạn sẽ không viết XPath giống như Nokogiri tạo ra. Ví dụ, hãy xem nếu bạn có thể đoán XPath cho hai câu lệnh CSS sau:
puts Nokogiri::CSS.xpath_for('#foo')
#=> //*[@id = 'foo']
puts Nokogiri::CSS.xpath_for 'div.article a.external'
#=> //div[contains(concat(' ', @class, ' '), ' article ')]//a[contains(concat(' ', @class, ' '), ' external ')]
Không giống như một trình duyệt Web, id
và class
thuộc tính không có bộ nhớ cache tăng tốc lên, vì vậy việc lựa chọn cho họ không giúp đỡ. Thật vậy, việc giải thích chung của div.article
liên quan đến công việc nhiều hơn so với một cái gì đó như div[@class='article']
.
Như @LBg đã nhận xét, bạn nên chuẩn bị cho chính mình nếu tốc độ tuyệt đối là quan trọng.
Tuy nhiên, tôi sẽ đề xuất điều này: đừng lo lắng về điều đó. Máy tính là nhanh. Viết những gì thuận tiện nhất cho bạn, lập trình viên. Nếu bộ chọn CSS dễ dàng hơn để tạo thủ công, nhanh hơn để nhập và dễ hiểu hơn khi xem lại mã của bạn sau, hãy sử dụng số đó. Sử dụng XPath khi bạn cần làm những việc mà bạn không thể làm với cú pháp bộ chọn CSS.
Mất bao lâu để Nokogiri chuyển đổi CSS phức tạp hợp lý thành XPath?
t = Time.now
1000.times do |i|
# Use a different CSS string each time to avoid built-in caching
css = "body#foo table#bar#{i} thead th, body#foo table#bar#{i} tbody td"
Nokogiri::CSS.xpath_for(css)
end
puts (Time.now - t)/1000
#=> 0.000405041
Ít hơn nửa mili giây.
Hmm, đó chính là XPath tôi sẽ viết. :) Cách thứ hai sử dụng lớp "lừa" bạn phải sử dụng khi phân tích cú pháp thuộc tính lớp HTML, có thể có nhiều giá trị được phân tách bằng dấu cách. –
@Phrogz, "Bộ chọn CSS được chuyển thành XPath bên trong trước khi yêu cầu libxml2 thực hiện truy vấn. Vì vậy, đối với cùng một bộ chọn, phiên bản XPath sẽ nhanh hơn một chút, vì CSS không cần phải chuyển đổi thành XPath Đầu tiên." Bạn đã quên cho phép thời gian gãi đầu cố gắng nhớ cách viết trình truy cập trong XPath. :-) –
+1 cho "đừng lo lắng về điều đó". Zactly! Dễ hiểu hơn có lợi ích lâu dài trong việc duy trì mã. Tôi không lo lắng nhiều về thời gian của máy tính, đó là thời gian của tôi đã cố gắng để hiểu những gì đã được viết mà tôi quan tâm. –
Xem ['Điểm chuẩn'] (http://www.ruby-doc.org/stdlib-1.9.3/libdoc/benchmark/rdoc/Benchmark.html). –