java中从char[],start,length创建字符串的有效方法

r7s23pms  于 2021-06-30  发布在  Java
关注(0)|答案(3)|浏览(381)

我们使用javasax来解析非常大的xml文件。我们的 characters 实现如下所示:

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

( ch[] sax传递的数组往往相当长)
但我们最近遇到了一些性能问题,profiler向我们显示,超过20%的cpu使用率高于调用 String.copyValueOf (其中 new String(ch,start,length) 在引擎盖下)。
有没有比从字符数组、起始索引和长度中获取字符串更有效的方法 String.copyValueOf(ch, start, length) 或者 new String(ch,start,length) ?

wmomyfyw

wmomyfyw1#

好问题,但我肯定,答案是否定的。
这是因为 String 对象构造使用数组复制方法。它不能直接在exist数组上构造,因为 String 对象必须是不可变的,并且其内部字符串数组表示形式由外部更改封装。
此外,在您的例子中,您处理了某个数组的片段。建造是不可能的 String 以任何方式在另一个数组的片段上。

rkue9o1l

rkue9o1l2#

可能是同时发生的 characters 在一个标记中可能被多次调用,在元素级别上持有stringbuilder可能是合适的。这是一个 System.arrayCopy .

lg40wkob

lg40wkob3#

正如@andremoniy所说的,如果你想使用一个string对象,总是要创建它,并将内容复制到其中。
提高解析器速度的唯一可能是将新构建的字符串对象的数量减少到最小。
我怀疑,xml结构中的每个元素都包含起始标记和结束标记之间的原始数据。
因此,我建议仅在数据感兴趣的元素中创建字符串。此外,我建议以某种方式限制可能的因素。例如,通过层次结构级别或父元素来减少stringcompaison的数量。但这取决于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;
}

相关问题