小编Lou*_* Go的帖子

continue in 循环严重减慢了 clang 的运行时间

问题

我遇到一道leetcode题加油站

但是我发现如果我使用if/else而不是我的代码会稍微快一些if/continue
编辑:在摆弄测试用例之后。我发现问题是continue
clang 似乎正在continue认真对待..?我的猜测是 hat clang 以某种方式尝试将继续和循环检查之前的部分放在一起。

简而言之:我想知道:

  • 我如何“说服” clang 理解我关于 continue 的实现,就像 if/else 一样?因为我不想改变我的编码风格。

编辑旁注:删除分支预测标签。

相关问题

我应该使用 return/continue 语句而不是 if-else 吗?看起来它们应该几乎没有区别。

调查

编辑:演示显示问题是continue

我用10k的数据集测试代码,发现问题出在continue本身。
我把 放在continuebodyif的末尾,然后运行时间增加了30% ~ 50%,这仍然让我感到惊讶。
现场演示
数量差异:11070 至 15060(带continue

编辑于 2022/5/30:抱歉,我发现我之前的天真分析错误地优化了部分计算...这导致了 100 的差异... 糟糕的演示

分析代码

#include <iostream>
#include <vector>
#include <chrono>
#include <cstdlib>

using namespace std; // Yeah I know it's …
Run Code Online (Sandbox Code Playgroud)

c++ assembly x86-64 clang

6
推荐指数
1
解决办法
468
查看次数

知道使用 std::once_flag 而不调用 std::call_once (任务成功完成后设置once_flag)

编辑:这是一个 XY 问题,但也保留原始标题。它可能会帮助其他有相同 XY 问题的人。目标应该是:“有std::once_flag任务成功完成后才翻转”。

使用案例

  1. 初始化只需完成一次,并且可以同时调用。
  2. 在调用初始化之前,需要进行验证。
  3. 如果已经初始化,则不需要验证。

问题

我如何不使用g_init(在下面的示例中)同时避免filesystem::exists()

限制

  1. 我无法修改调用者,这是我无法更改的基础设施。
  2. cfg["PATH"]未知,只能由调用者提供。

欢迎C++20或C++23等解决方案。最好是标准或自制解决方案。也可能是XY问题......

简化的演示

#include <mutex>
#include <filesystem>
#include <atomic>
#include "fmt/core.h"
#include "nlohmann/json.hpp"
using json = nlohmann::json;
std::once_flag g_flag;
std::atomic<bool> g_init{false};

void doOnce(std::string path){
    // initializing from file...
    fmt::print("initialization done");
}

void doWork(json& cfg){
    // Atomic flag for 
    if(g_init) {
        fmt::print("already inited");
        return;
    }

    std::string path = cfg["PATH"];
    if(!std::filesystem::exists(path)){
        fmt::print("load failed");
        return;
    }
    std::call_once(g_flag, doOnce, path);
}

int main() …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading initialization c++11

2
推荐指数
1
解决办法
159
查看次数

标签 统计

c++ ×2

assembly ×1

c++11 ×1

clang ×1

initialization ×1

multithreading ×1

x86-64 ×1