2013-06-06 30 views
7

Chúng tôi đang sử dụng Java SAX để phân tích cú pháp trên các tệp XML thực sự lớn. thực hiện characters của chúng tôi trông giống như sau:Cách hiệu quả để tạo chuỗi từ char [], bắt đầu, chiều dài trong Java

@Override 
public void characters(char ch[], int start, int length) throws SAXException { 
    String value = String.copyValueOf(ch, start, length); 
    ... 
} 

(ch[] mảng thông qua SAX có xu hướng được khá lâu)

Nhưng gần đây chúng ta đang nhận được một số vấn đề hiệu suất và các hồ sơ cho chúng ta thấy rằng hơn 20% CPU của chúng tôi mức sử dụng cao hơn yêu cầu String.copyValueOf (được gọi new String(ch,start,length) dưới mui xe).

Có cách nào hiệu quả hơn để lấy Chuỗi từ chuỗi ký tự, chỉ mục bắt đầu và độ dài hơn String.copyValueOf(ch, start, length) hoặc new String(ch,start,length) không?

+0

Nó có thể tồi tệ hơn, nhưng bạn đã thử một 'StringBuilder' chưa? 'String mới (ch, start, length)' chỉ sao chép mảng trên nhưng tôi không biết công việc 'StringBuilder' có thể nhanh đến mức nào. – Djon

+1

Chuỗi được tạo không được trả lại. Bạn sẽ làm gì với nó? Có thể đó được thực hiện với chuỗi đó cũng được thực hiện trực tiếp trên char [] với bắt đầu và chiều dài? – Fildor

+0

@Fildor Vâng, tôi đã nghĩ về điều đó. Nhưng chúng tôi thực hiện nhiều hoạt động khác nhau với chúng tôi, nơi chúng tôi xử lý nó dưới dạng Chuỗi. Nó sẽ là cực kỳ khó (hoặc ít nhất là mã sẽ thực sự xấu xí) để hoạt động trên mảng char. –

Trả lời

4

Câu hỏi hay, nhưng tôi chắc chắn, câu trả lời là không.

Điều này là do bất kỳ công trình xây dựng đối tượng nào sử dụng phương thức sao chép mảng String. Nó không thể được xây dựng trực tiếp trên mảng tồn tại, vì đối tượng String phải không thay đổi và biểu diễn mảng chuỗi bên trong của nó được đóng gói từ các thay đổi bên ngoài.

Ngoài ra, trong trường hợp của bạn, bạn có thỏa thuận với một đoạn của một số mảng. Không thể xây dựng đối tượng String trên đoạn của mảng khác theo bất kỳ cách nào.

1

Như đã nêu bởi @Andremoniy, nếu bạn muốn sử dụng một đối tượng String, nó luôn luôn phải được tạo và nội dung được sao chép vào nó.

Khả năng duy nhất để tăng tốc trình phân tích cú pháp của bạn là giảm số lượng đối tượng chuỗi mới xây dựng ở mức tối thiểu.

Tôi doupt, rằng mọi phần tử trong cấu trúc xml của bạn đều chứa dữ liệu thô giữa thẻ bắt đầu và thẻ kết thúc.

Do đó, tôi khuyên bạn chỉ nên tạo các chuỗi nếu bạn ở trong phần tử nơi dữ liệu được quan tâm. Hơn nữa tôi sẽ đề nghị hạn chế các yếu tố có thể bằng cách nào đó. Ví dụ theo cấp bậc hoặc phần tử cha để giảm số lượng chuỗi ký tự. Nhưng điều này phụ thuộc vào cấu trúc xml.

protected boolean readChars = false; 
protected int level = -1; 

@Override 
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 
    ++level; 

    if (level == 4) { 
     if (qName.equalsIgnoreCase("TextElement")) { 
      readChars = true; 
     } 
    } 
} 

@Override 
public void characters(char ch[], int start, int length) throws SAXException { 
    if (readChars) { 
     String value = String.copyValueOf(ch, start, length); 
     ... 
     readChars = false; 
    } 
} 

@Override 
public void endElement(String uri, String localName, String qName) throws SAXException { 
    --level; 
} 
1

Có thể kết hợp, mà characters có thể được gọi nhiều hơn một lần trong một thẻ duy nhất, cầm một StringBuilder vào mức độ yếu tố có thể là thích hợp. Điều này thực hiện một System.arrayCopy.

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