如何解决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 举报,一经查实,本站将立刻删除。