My friend and I compared zig and cpp based on this little code snippet. Mine is from a little program i made, his is an attempt at recreating what I did. Thing is, that I can’t read cpp and he cant read zig, at least not to an extent where either of us could figure out what could have made the performance difference between our snippets.
Can anyone figure out why his was faster? If so, what were the differences?
My code:
// measuring how long it takes to load the file
const file_loading_start_time = std.time.milliTimestamp();
var files = std.ArrayList([]const u8).init(allocator);
defer files.deinit();
var dir = try fs.cwd().openDir(resource_path, .{});
defer dir.close();
var resource_dir = try fs.cwd().openIterableDir(resource_path, .{});
defer resource_dir.close();
var resource_iter = resource_dir.iterate();
while (try resource_iter.next()) |ifile| {
if (ifile.kind != .file) {
continue;
}
const file = try dir.openFile(ifile.name, .{});
defer file.close();
const file_contents = try file.readToEndAlloc(allocator, math.maxInt(usize));
errdefer allocator.free(file_contents);
try files.append(file_contents);
try stdout.print("[SYSTEM] Loaded {s: >32}\n", .{ifile.name});
}
if (files.items.len == 0) {
try stdout.print("[ERROR] No files found", .{});
os.exit(1);
}
defer for (files.items) |file|
allocator.free(file);
// measuring how long it takes to load the file
try stdout.print("took {d}ms", .{std.time.milliTimestamp() - file_loading_start_time});
His code:
std::chrono::time_point Start = std::chrono::high_resolution_clock::now();
// GetCurrentPath
char buffer[MAX_PATH];
GetModuleFileNameA(nullptr, buffer, MAX_PATH);
std::string Path(buffer);
size_t pos = Path.find_last_of("\\");
if (pos != std::string::npos) {
Path = Path.substr(0, pos);
}
Path += "\\resources";
// Iterate over files
std::vector<std::string> out;
WIN32_FIND_DATAA findData;
HANDLE findHandle = FindFirstFileA((Path + "\\*").c_str(), &findData);
if (findHandle != INVALID_HANDLE_VALUE) {
do {
std::string fileName = findData.cFileName;
if (fileName == "." || fileName == "..")
continue;
std::string fullPath = Path + "\\" + fileName;
bool isFolder = (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
out.push_back(fullPath);
} while (FindNextFileA(findHandle, &findData) != 0);
FindClose(findHandle);
}
std::string Data;
// Memory map files
for (const std::string& Path : out) {
HANDLE FileHandle = CreateFileA(Path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
LARGE_INTEGER FileSize;
GetFileSizeEx(FileHandle, &FileSize);
HANDLE MappingHandle = CreateFileMapping(FileHandle, NULL, PAGE_READWRITE, FileSize.HighPart, FileSize.LowPart, NULL);
void* MappedPtr = MapViewOfFile(MappingHandle, FILE_MAP_WRITE, 0, 0, 0);
Data += (char*)MappedPtr;
UnmapViewOfFile(MappedPtr);
CloseHandle(MappingHandle);
CloseHandle(FileHandle);
}
std::chrono::time_point End = std::chrono::high_resolution_clock::now();
float duration = std::chrono::duration_cast<std::chrono::milliseconds>(End - Start).count();
std::cout << duration << "ms" << std::endl;