1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
/*
SPDX-FileCopyrightText: 2014 Benjamin Kaiser <benjaminjkaiser@gmail.com>
SPDX-License-Identifier: MIT
*/
#include <QDebug>
#include "duchaindebug.h"
#include "duchainbench.h"
#include <language/duchain/topducontext.h>
#include <language/codegen/coderepresentation.h>
#include <tests/autotestshell.h>
#include <tests/testcore.h>
#include <language/duchain/duchain.h>
#include <QtTest>
#include <language/backgroundparser/backgroundparser.h>
#include <interfaces/ilanguagecontroller.h>
#include <QStandardPaths>
#include "parsesession.h"
QTEST_MAIN(DUChainBench)
using namespace KDevelop;
using namespace Python;
DUChainBench::DUChainBench(QObject* parent): QObject(parent)
{
testDir = QDir(testDirOwner.path());
initShell();
}
void DUChainBench::initShell()
{
AutoTestShell::init();
TestCore* core = new TestCore();
core->initialize(KDevelop::Core::NoUi);
auto doc_url = QDir::cleanPath(QStandardPaths::locate(QStandardPaths::GenericDataLocation,
QStringLiteral("kdevpythonsupport/documentation_files/builtindocumentation.py")));
DUChain::self()->updateContextForUrl(IndexedString(doc_url), KDevelop::TopDUContext::AllDeclarationsContextsAndUses);
ICore::self()->languageController()->backgroundParser()->parseDocuments();
DUChain::self()->waitForUpdate(IndexedString(doc_url), KDevelop::TopDUContext::AllDeclarationsContextsAndUses);
DUChain::self()->disablePersistentStorage();
KDevelop::CodeRepresentation::setDiskChangesForbidden(true);
}
ReferencedTopDUContext DUChainBench::parse(const QString& code)
{
TestFile* testfile = new TestFile(code + QLatin1Char('\n'), QStringLiteral("py"), nullptr, testDir.absolutePath().append(QLatin1Char('/')));
createdFiles << testfile;
testfile->parse(TopDUContext::ForceUpdate | TopDUContext::AST);
testfile->waitForParsed(2000);
if ( testfile->isReady() ) {
m_ast = static_cast<Python::ParseSession*>(testfile->topContext()->ast().data())->ast;
return testfile->topContext();
}
else Q_ASSERT(false && "Timed out waiting for parser results, aborting all tests");
return nullptr;
}
DUChainBench::~DUChainBench()
{
for (TestFile* f : std::as_const(createdFiles)) {
delete f;
}
testDir.rmdir(testDir.absolutePath());
}
QString repeat_distinct(const QString& code, int count) {
QString result;
QString line;
for ( int i = 0; i < count; i++ ) {
line = code;
result.append(line.replace(QStringLiteral("%X"), QString::number(i)));
}
return result;
}
void DUChainBench::benchSimpleStatements_data()
{
QTest::addColumn<QString>("code");
// test assignment
QTest::newRow("test_nondistinct_assignment_repeated") << QStringLiteral("a=3\n").repeated(200);
QTest::newRow("test_nondistinct_assignment_looped") << repeat_distinct(QStringLiteral("a=%X\n"), 200);
QTest::newRow("test_distinct_assignment_repeated") << repeat_distinct(QStringLiteral("a%X=3\n"), 200);
QTest::newRow("test_distinct_assignment_looped") << repeat_distinct(QStringLiteral("a%X=%X\n"), 200);
// test function
QTest::newRow("test_bare_function") << repeat_distinct(QStringLiteral("def main%X():\n pass\n"), 100);
QTest::newRow("test_return_function") << repeat_distinct(QStringLiteral("def main%X():\n return %X\n"), 100);
QTest::newRow("test_arg_function_return_var") << repeat_distinct(QStringLiteral("def func%X(arg):\n return arg\na%X = func%X(3)\n"), 200);
QTest::newRow("test_arg_function_return_fixed") << repeat_distinct(QStringLiteral("def func%X(arg):\n return 3\na%X = func%X()\n"), 200);
// test if statements
QTest::newRow("test_if_statement") << repeat_distinct(QStringLiteral("if(True):\n pass\n"), 200);
QTest::newRow("test_if_else_statement") << repeat_distinct(QStringLiteral("if(True):\n pass\nelse:\n pass\n"), 200);
// test for loops
QTest::newRow("test_for_loop") << repeat_distinct(QStringLiteral("for i in range(20):\n pass\n"), 100);
QTest::newRow("test_for_loop_enum") << repeat_distinct(QStringLiteral("for key, value in enumerate({1:2, 7:3}):\n pass\n"), 200);
QTest::newRow("test_for_loop_list") << repeat_distinct(QStringLiteral("for key, value in [(3, 5), (7, 9)]:\n pass\n"), 200);
}
void DUChainBench::benchSimpleStatements()
{
QFETCH(QString, code);
QBENCHMARK {
parse(code);
}
}
#include "moc_duchainbench.cpp"
|