Page 199 - 《软件学报》2026年第2期
P. 199

678                                                        软件学报  2026  年第  37  卷第  2  期


                                  表 6    含子函数信息的输入对       DHCS  和  baseline 模型的影响 (%)(续)

                                        BLEU-4                  METEOR                   ROUGE-L
                      方法
                                 Python   Java    Go     Python   Java     Go     Python   Java    Go
                    StarCoder    16.90   17.25   14.75    17.27   17.53   14.43    17.29   22.97   17.92
                   StarCoder_wsf  16.83  17.45   14.62    17.07   17.44   14.34    16.97   18.43   17.65
                      EACS       18.10   16.38   17.28    17.09   16.50   17.36    34.70   35.54   37.20
                    EACS_wsf     17.89   16.29   17.27    16.92   15.04   17.12    33.40   32.27   37.00
                      DHCS       18.62   18.59   18.05    17.63   16.60   17.92    34.99   35.69   37.42
                  5.7.2    函数名称对任务的影响
                    在编写代码时, 程序员通常会为函数命名以增强对代码功能的理解. 因此, 函数名称本身可能部分地反映了函
                 数的目的. 例如, 名为“searchAccession”的函数意味着其功能可能与搜索             Accession  有关, 并可能涉及其他操作, 按
                 照驼峰命名法的惯例. 然而, 这种做法可能会使代码注释生成模型过分关注函数的名称, 而忽略代码的实际逻辑和
                 功能. 因此, 本文进行实证研究, 以了解函数名称对代码注释性能的影响.
                    本文采用了两种策略来操控目标函数中的函数名称: 掩码                  (masking) 和随机替换   (random replacement). 在掩码
                 策略中, 使用特殊     token “<mask>”来隐藏函数名称; 而在随机替换策略中, 从数据集中的其他目标函数中随机选择一
                 个函数名称并将其替换为原始函数名称. 这两种策略帮助本研究代码注释生成模型在处理函数名称变化时的鲁棒性.
                    从表  7  中可以看出, 所有模型在函数名称进行掩码或替换时都受到了影响. 在                     baseline 模型中, CodeT5  对函
                 数名称变化的鲁棒性较强, 这得益于其标识符感知的预训练机制. 与此类似, 本文方法也展现了较好的表现.

                                          表 7 函数名称对代码注释生成任务的影响 (%)

                                             BLEU-4                METEOR                 ROUGE-L
                    不同策略下的方法
                                        Python      Java       Python      Java       Python      Java
                       RoBERTa           10.37      10.98       8.11      10.17       17.10      23.40
                     RoBERTa (mfn)       10.37      8.97        8.11       6.83       17.10      17.11
                      RoBERTa (rfn)      10.36      9.03        8.11       7.71       17.09      18.74
                       CodeBERT          14.87      12.77      13.65      11.47       28.09      25.75
                     CodeBERT (mfn)      13.41      11.45      12.24      10.27       24.84      23.44
                     CodeBERT (rfn)      11.79      11.51       9.62      10.94       21.06      24.33
                       UniXcoder         17.22      15.61      15.19      13.48       30.51      30.18
                     UniXcoder (mfn)     14.50      13.69      12.98      12.29       25.47      27.63
                     UniXcoder (rfn)     13.95      14.30      12.77      12.37       24.96      28.14
                        CodeT5           17.69      16.22      17.19      14.93       34.03      32.00
                      CodeT5 (mfn)       15.67      14.54      15.26      13.74       30.04      29.85
                      CodeT5 (rfn)       15.84      14.46      15.33      13.70       30.28      29.77
                         DHCS            18.62      18.59      17.63      16.60       34.99      35.69
                       DHCS (mfn)        16.36      16.39      15.65      15.36       30.63      32.73
                       DHCS (rfn)        16.37      16.35      15.77      15.33       30.64      32.62
                 注: “mfn”表示掩码策略, “rfn”表示随机替换策略
                  5.8   案例研究

                    为了进一步突出       DHCS  的有效性, 如图   7  所示, 本文提供了    4  个代码注释的示例案例. 案例       1  关于  Python  语
                 言, 案例  2  和案例  3  关于  Java 语言, 案例  4  关于  Go  语言. 值得注意的是, 案例  1、2  和案例  4  包含了一个子函数的
                 调用, 而案例   3  包含了  3  个子函数的调用. 在    BLEU-4、METEOR  和  ROUGE-L  这  3  个关键指标上, DHCS  表现出
                 显著优于   baseline 模型  CodeT5  和  StarCoder 的优势.
                    通常, 子函数是目标函数功能的主要驱动力. 例如, 在图               7  中的案例  1  中, 目标函数“reencrypt_user_content”调
                 用了子函数“reencrypt_row_content”. 通过引入子函数, 可以看到关键信息位于第             2  个参数中. 因此, 可以推断出,
                 两个  for 循环使得子函数可以分别对文件和检查点进行重新加密. 因此, 生成的注释更加准确, 更好地反映了目标
                 函数的目的. 相比之下, 由于没有包含子函数信息, 两个              baseline 模型生成的注释更为笼统.
   194   195   196   197   198   199   200   201   202   203   204