perf: reduce allocations across UI and editor hot paths

- reuse formatting, document text, property resolution, and layout storage
  - use inline containers for interpolations, callbacks, wrapping, and matcher state
  - optimize single-line insertion by mutating document lines without splitting
  - iterate PATH entries directly in Sys::which and reuse candidate buffers
  - avoid temporary clocks and string copies in frequent ecode plugin updates
  - retain documents during autocomplete cache jobs and prevent duplicate scheduling
  - fix PatternMatcher copy assignment and MSVC move-only container compilation
  - expand coverage for matching, text insertion, reusable strings, and Sys::which
This commit is contained in:
Martín Lucas Golini
2026-08-09 21:38:17 -03:00
parent 5f419ca58d
commit 23cf9084ce
35 changed files with 618 additions and 189 deletions

View File

@@ -1,13 +1,71 @@
#include "utest.h"
#include <cstdlib>
#include <eepp/core/string.hpp>
#include <eepp/system/filesystem.hpp>
#include <eepp/system/sys.hpp>
#include <filesystem>
using namespace std::literals;
using namespace EE;
using namespace EE::System;
namespace {
class ScopedEnvironmentVariable {
public:
ScopedEnvironmentVariable( const char* name, const std::string& value ) : mName( name ) {
if ( const char* currentValue = std::getenv( name ) ) {
mHadValue = true;
mValue = currentValue;
}
set( value.c_str() );
}
~ScopedEnvironmentVariable() {
if ( mHadValue )
set( mValue.c_str() );
else
unset();
}
private:
void set( const char* value ) {
#if EE_PLATFORM == EE_PLATFORM_WIN
_putenv_s( mName, value );
#else
setenv( mName, value, 1 );
#endif
}
void unset() {
#if EE_PLATFORM == EE_PLATFORM_WIN
_putenv_s( mName, "" );
#else
unsetenv( mName );
#endif
}
const char* mName;
std::string mValue;
bool mHadValue{ false };
};
class ScopedTestDirectory {
public:
explicit ScopedTestDirectory( std::filesystem::path path ) : mPath( std::move( path ) ) {}
~ScopedTestDirectory() {
std::error_code error;
std::filesystem::remove_all( mPath, error );
}
private:
std::filesystem::path mPath;
};
} // namespace
UTEST( String, countLines ) {
EXPECT_EQ( static_cast<size_t>( 0 ), String::countLines( "" ) );
EXPECT_EQ( static_cast<size_t>( 1 ), String::countLines( "A" ) );
@@ -30,6 +88,23 @@ UTEST( String, fromStringView ) {
EXPECT_EQ( 1234, intValue );
}
UTEST( String, reusableFormattingAndUtf8Assignment ) {
std::string formatted;
formatted.reserve( 128 );
const char* formattedStorage = formatted.data();
String::formatTo( formatted, "%s: %d", std::string_view{ "line" }, 42 );
EXPECT_STREQ( "line: 42", formatted.c_str() );
EXPECT_EQ( formattedStorage, formatted.data() );
String text;
text.reserve( 128 );
const auto* textStorage = text.getString().data();
text.assignUtf8( "áβ中" );
const std::string utf8Text = text.toUtf8();
EXPECT_STREQ( "áβ中", utf8Text.c_str() );
EXPECT_EQ( textStorage, text.getString().data() );
}
UTEST( FileSystem, fileCountLines ) {
std::string path = Sys::getTempPath() + "eepp_test_count_lines.txt";
FileSystem::fileWrite( path, "A\nB\nC" );
@@ -57,6 +132,60 @@ UTEST( FileSystem, fileCountLines ) {
FileSystem::fileRemove( path );
}
UTEST( Sys, whichUsesPathAndCustomSearchPaths ) {
const std::filesystem::path root = std::filesystem::path( Sys::getTempPath() ) /
( "eepp-sys-which-" + std::to_string( Sys::getProcessID() ) +
"-" + std::to_string( Sys::getTicks() ) );
ScopedTestDirectory cleanup( root );
const std::filesystem::path firstDir = root / "first";
const std::filesystem::path secondDir = root / "second";
ASSERT_TRUE( std::filesystem::create_directories( firstDir ) );
ASSERT_TRUE( std::filesystem::create_directories( secondDir ) );
#if EE_PLATFORM == EE_PLATFORM_WIN
static constexpr auto EXECUTABLE_NAME = "eepp-which-probe.EXE";
static constexpr auto LOOKUP_NAME = "eepp-which-probe";
static constexpr auto PATH_SEPARATOR = ';';
ScopedEnvironmentVariable pathExt( "PATHEXT", ".COM;.EXE;.BAT;.CMD" );
#else
static constexpr auto EXECUTABLE_NAME = "eepp-which-probe";
static constexpr auto LOOKUP_NAME = EXECUTABLE_NAME;
static constexpr auto PATH_SEPARATOR = ':';
#endif
const std::filesystem::path firstExecutable = firstDir / EXECUTABLE_NAME;
const std::filesystem::path secondExecutable = secondDir / EXECUTABLE_NAME;
ASSERT_TRUE( FileSystem::fileWrite( firstExecutable.string(), "first" ) );
ASSERT_TRUE( FileSystem::fileWrite( secondExecutable.string(), "second" ) );
#if EE_PLATFORM != EE_PLATFORM_WIN
std::error_code permissionError;
const auto executablePermissions = std::filesystem::perms::owner_exec |
std::filesystem::perms::group_exec |
std::filesystem::perms::others_exec;
std::filesystem::permissions( firstExecutable, executablePermissions,
std::filesystem::perm_options::add, permissionError );
ASSERT_FALSE( permissionError );
std::filesystem::permissions( secondExecutable, executablePermissions,
std::filesystem::perm_options::add, permissionError );
ASSERT_FALSE( permissionError );
#endif
const std::string path = firstDir.string() + PATH_SEPARATOR + secondDir.string();
ScopedEnvironmentVariable scopedPath( "PATH", path );
EXPECT_TRUE( Sys::which( LOOKUP_NAME ) == firstExecutable.string() );
EXPECT_TRUE( Sys::which( firstExecutable.string() ) == firstExecutable.string() );
EXPECT_TRUE( Sys::which( "eepp-which-missing" ).empty() );
FileSystem::fileRemove( firstExecutable.string() );
EXPECT_TRUE( Sys::which( LOOKUP_NAME ) == secondExecutable.string() );
ScopedEnvironmentVariable emptyPath( "PATH", "" );
EXPECT_TRUE( Sys::which( LOOKUP_NAME ).empty() );
EXPECT_TRUE( Sys::which( LOOKUP_NAME, { firstDir.string(), secondDir.string() } ) ==
secondExecutable.string() );
}
UTEST( String, isAscii ) {
// Empty string
EXPECT_TRUE( String::isAscii( String::View( U"" ) ) );