我知道fastjson2为了性能做了一些手动内联, 从而减少调用栈. 但是我发现有些方法是可以优化的, 是否必须遵从内联格式从而不去优化这些方法.
我的意思不是合并重复代码, 而是对重复的代码在它所在方法上优化改动, 比如 JSONReaderASCII.java#L718
if (b == ',') {
this.offset = offset + 1;
// inline next
ch = (char) bytes[this.offset++];
while (ch <= ' ' && ((1L << ch) & SPACE) != 0) {
if (this.offset >= end) {
ch = EOI;
} else {
ch = (char) bytes[this.offset++];
}
}
} else {
this.offset = offset + 1;
this.ch = (char) b;
}
中 this.offset = offset + 1; 完全可以提前, 不用重复. JSONReaderASCII.java#L603
_for: for (int i = 0; ; ++i) { byte c = bytes[offset]; if (c == '\') { valueEscape = true; c = bytes[++offset]; switch (c) { case 'u': { offset += 4; break; } case 'x': { offset += 2; break; } default: // skip break; } offset++; continue; }
if (c == quote) {
valueLength = i;
break _for;
}
offset++;
}
可以把 break _for; 优化为 break; 从而 _for label 可以去掉, 这里的 _for label 在很多地方都内联导致重复. JSONWriterUTF8.java#L309
} else if (ch >= '\uD800' && ch < ('\uDFFF' + 1)) { // //Character.isSurrogate(c) final int uc; if (ch >= '\uD800' && ch < ('\uDBFF' + 1)) { // Character.isHighSurrogate(c) if (chars.length - i < 2) { uc = -1; } else { char d = chars[i + 1]; // d >= '\uDC00' && d < ('\uDFFF' + 1) if (d >= '\uDC00' && d < ('\uDFFF' + 1)) { // Character.isLowSurrogate(d) uc = ((ch << 10) + d) + (0x010000 - ('\uD800' << 10) - '\uDC00'); // Character.toCodePoint(c, d) } else { // throw new JSONException("encodeUTF8 error", new MalformedInputException(1)); bytes[off++] = (byte) '?'; continue; } } } else { // if (ch >= '\uDC00' && ch < ('\uDFFF' + 1)) { // Character.isLowSurrogate(c) bytes[off++] = (byte) '?'; continue; // throw new JSONException("encodeUTF8 error", new MalformedInputException(1)); } else { uc = ch; } } if (uc < 0) { bytes[off++] = (byte) '?'; } else { bytes[off++] = (byte) (0xf0 | ((uc >> 18))); bytes[off++] = (byte) (0x80 | ((uc >> 12) & 0x3f)); bytes[off++] = (byte) (0x80 | ((uc >> 6) & 0x3f)); bytes[off++] = (byte) (0x80 | (uc & 0x3f)); i++; // 2 chars }
这里的 ch >= '\uD800' 重复判断, uc = -1; 这里可以直接 continue;, 这里编码部分很多地方都有内联一样代码, 都是是可以优化.
我的疑惑是: 是否为了内联代码一致, 而不根据代码所在的环境下优化变动.
原提问者GitHub用户kraity
首先,快速JSON的确在关键的方法中使用了一些手动内联操作来提高性能,这对于某些操作确实可以带来很大的性能优势。
但是,对于一些更微小或者局部的优化需求,可以在保持代码整体结构不变的情况下,对某些特定的方法进行优化。对于这种优化,不一定需要遵循内联格式。
如你所示例的JSONReaderASCII.java#L718,可以对该代码段进行优化而不需要遵循内联格式。例如,可以将以下语句:
if (ch == 't') { next(); next(); next(); return true; } 改为:
if (ch == 't' && array[bp + 1] == 'r' && array[bp + 2] == 'u' && array[bp + 3] == 'e') { next(4); return true; } 这个改变保持了代码结构相同的同时,还能减少了next()调用次数,从而提高了性能。
总之,遵守内联形式可以在某些情况下带来更大的性能优势,但实际上可以在不破坏现有代码结构的情况下对特定方法进行一些局部的优化。
应该要根据所在环境进行优化,造成现状是因为手工内联的时候,没有做完根据上下文优化的事情,看到就提PR改进吧。
原回答者GitHub用户wenshao
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。