开发者社区> 问答> 正文

关于fastjson2 性能和优化疑问

我知道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

展开
收起
大圣东游 2023-04-21 12:28:07 687 0
3 条回答
写回答
取消 提交回答
  • 值得去的地方都没有捷径

    首先,快速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()调用次数,从而提高了性能。

    总之,遵守内联形式可以在某些情况下带来更大的性能优势,但实际上可以在不破坏现有代码结构的情况下对特定方法进行一些局部的优化。

    2023-04-21 20:08:21
    赞同 展开评论 打赏
  • 应该要根据所在环境进行优化,造成现状是因为手工内联的时候,没有做完根据上下文优化的事情,看到就提PR改进吧。

    原回答者GitHub用户wenshao

    2023-04-21 15:08:10
    赞同 展开评论 打赏
  • GitHub https://github.com/co63oc/cloud

    代码显示不完全 image.png

    2023-04-21 14:32:38
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载