Clang PCH性能比标头差吗?

问题描述

我有一组包含在源文件中的标头,这些标头很少/从未更改。解析/解析使用标头的频繁更改的源文件(IDE用例)花费的时间太长(几秒钟)。为了提高性能,我想使用Clang PCH。请注意,我要在Android上以“发布”模式(肯定达到99%)编译libclang(不是最新版本)。

我一直遵循answer to a similar question,但与标头解析(带有100000个#define宏的人工标头)相比,使用PCH的性能要差3倍:

2020-08-11 12:03:53.265 19767-19788 W/TranslationUnitTest: PCH parse time: 0.462277
2020-08-11 12:03:53.265 19767-19788 W/TranslationUnitTest: 0 diagnostics
2020-08-11 12:03:55.768 19767-19788 W/TranslationUnitTest: Source parse time: 1.456947
2020-08-11 12:03:55.768 19767-19788 W/TranslationUnitTest: 0 diagnostics

Java源代码(在Android Instrumentation测试中运行):

final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();

// create PCH
dir = new File(context.getCacheDir(),String.valueOf(Math.abs(new Random().nextLong())));
dir.mkdirs();

deeperHeaderFile = new File(dir,"deeperHeader.h");
StringBuilder sb = new StringBuilder("#define VAL 1 ");
for (int i=0; i<100000; i++) {
    sb.append("\n");
    sb.append("#define VAL" + i + " " + i);
}
setFileContent(deeperHeaderFile,sb.toString());

headerFile = new File(dir,"header.hxx");
setFileContent(headerFile,"#include \"deeperHeader.h\"");

pchFile = new File(dir,"header.pch");

sourceFile = new File(dir,"source.cpp");
setFileContent(sourceFile,"#include \"header.hxx\"\nint main() { return VAL; }");

// C++ test
Clang.testPch(
    pchFile.getAbsolutePath(),headerFile.getAbsolutePath(),deeperHeaderFile.getAbsolutePath(),sourceFile.getAbsolutePath());

C ++源代码:

class Timer {
public:
    Timer () {
      reset();
    }

    double get () {
      struct timeval now;
      gettimeofday (&now,NULL);

      return now.tv_sec - start_.tv_sec + 1e-6 * (now.tv_usec - start_.tv_usec);
    }

    void reset () {
      gettimeofday (&start_,NULL);
    }

private:
    struct timeval start_;
};

void displayDiagnostics(CXTranslationUnit TU) {
  if (TU == 0) {
    std::cerr << "Parsing error!" << std::endl;
    return;
  }

  int numDiagnostics = clang_getNumDiagnostics (TU);

  __android_log_print(ANDROID_LOG_WARN,TAG,"%d diagnostics",numDiagnostics);

  for (int i=0 ; i<numDiagnostics ; ++i) {
    auto diagnostic = clang_getDiagnostic(TU,i);
    auto string = clang_formatDiagnostic(diagnostic,clang_defaultDiagnosticDisplayOptions());
    auto cString = clang_getCString(string);

    __android_log_print(ANDROID_LOG_WARN,"diag #%d: %s",i,cString);

    clang_disposeString(string);
    clang_disposeDiagnostic(diagnostic);
  }
}

JNIEXPORT void JNICALL Clang_testPch(
    JNIEnv *env,jclass clazz,jstring jPchFilename,jstring jHeaderFilename,jstring jDeeperHeaderFilename,jstring jSourceFilename) {

  char *cPchFilename = string_copy(env,jPchFilename);
  char *cHeaderFilename = string_copy(env,jHeaderFilename);
  char *cDeeperHeaderFilename = string_copy(env,jDeeperHeaderFilename);
  char *cSourceFilename = string_copy(env,jSourceFilename);

  auto Idx = clang_createIndex (0,0);
  CXTranslationUnit TU;
  Timer t;

  {
    char const *args[] = { "-xc++",cHeaderFilename };
    int nargs = 2;

    t.reset();
    TU = clang_parseTranslationUnit(Idx,args,nargs,CXTranslationUnit_ForSerialization);
    auto pchParsetime = t.get();
    __android_log_print(ANDROID_LOG_WARN,"PCH parse time: %f",pchParsetime);
    displayDiagnostics(TU);
    clang_saveTranslationUnit(TU,cPchFilename,clang_defaultSaveOptions(TU));
    clang_disposeTranslationUnit(TU);
  }

  {
    char const *args[] = { "-include-pch",cSourceFilename };
    int nargs = 3;

    t.reset();
    TU = clang_createTranslationUnitFromSourceFile(Idx,0);
    auto parseTime = t.get();
    __android_log_print(ANDROID_LOG_WARN,"Source parse time: %f",parseTime);
    displayDiagnostics(TU);
    clang_disposeTranslationUnit(TU);
  }

  // release
  delete []cPchFilename;
  delete []cHeaderFilename;
  delete []cDeeperHeaderFilename;
  delete []cSourceFilename;
}

我相信文件是用Java编写的(原始原因是我具有clang绑定,并且Java代码具有相同的[坏]性能,所以我更改了要在C ++中测试的代码)

我想念什么吗?有愚蠢的错误吗?有什么建议吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...