RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 993519
Accepted
Sirop4ik
Sirop4ik
Asked:2020-06-17 15:22:31 +0000 UTC2020-06-17 15:22:31 +0000 UTC 2020-06-17 15:22:31 +0000 UTC

c++ 中的 foreach 和 std::for_each 有什么区别?

  • 772

我是 C++ 新手

我正在阅读一个示例,偶然发现了这样的结构std::for_each,但不明白为什么在有标准 for(val v : array) 时需要它?

运行时测试

#include <array>
#include <iostream>


#include <chrono>
#include <android/log.h>
#include <thread>
#include <fstream>
#include <utility>

using namespace std;
using namespace std::chrono;

void testDeleteIt() {
    std::vector<int> workers;

    for (int i = 0; i < 1000000; ++i) {
        workers.push_back(i);
    }

    int count = 0;

    high_resolution_clock::time_point t1 = high_resolution_clock::now();

    for (int &i : workers) {
        count += i;
    }

    __android_log_print(ANDROID_LOG_ERROR, "HERE", "HERE ::: %s", std::to_string(count).c_str());
    count = 0;

    long long int duration = duration_cast<microseconds>(high_resolution_clock::now() - t1).count();
    __android_log_print(ANDROID_LOG_ERROR, "TIME1", "TIME 1::: %s", std::to_string(duration).c_str());

    high_resolution_clock::time_point t2 = high_resolution_clock::now();


    std::for_each(workers.begin(), workers.end(), [&count](int &i) -> void {
        count += i;
    });

    count = 0;
    __android_log_print(ANDROID_LOG_ERROR, "HERE", "HERE ::: %s", std::to_string(count).c_str());

    duration = duration_cast<microseconds>(high_resolution_clock::now() - t2).count();
    __android_log_print(ANDROID_LOG_ERROR, "TIME2", "TIME 2 ::: %s", std::to_string(duration).c_str());
}

事实证明,标准循环的执行速度快了近 2 倍

TIME 1::: 10102
TIME 2 ::: 18459

再加std::for_each上 lambda 的麻烦

那么它的优势在哪里呢?

c++
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    KoVadim
    2020-06-17T15:57:51Z2020-06-17T15:57:51Z

    我正在阅读一个示例,遇到了这样的构造 std::for_each 并且不明白为什么当有标准 for(val v : array) 时需要它?

    这很简单——std::for_each它至少早在 10 年前就出现了。所以,是的,现在有一个标准。但你不是唯一一个问这个问题的人。

    但是有几个特点。std::for_each有几个附加功能。

    • std::for_each可以使用两个迭代器给定的任意范围。只能做begin-end的标准。
    • std::for_each您可以为您的类型重载并使循环“更快” - 因为该函数将知道您的类型的内部。
    • 在 17 岁时,他们带来了标准execution_policy。这意味着通过轻微的移动,您可以使其成为for_each“多线程”,并且容器的处理速度会更快。

    在答案中,您正在测试求和。然后使用std::accumulate. 我怀疑在第一种情况下,编译器弄清楚了您到底在总结什么,并简单地将其替换为“系列之和”公式。Clang 确切地知道如何做。在这种情况下,比较两个循环的性能有点不正确。

    • 20
  2. AR Hovsepyan
    2020-06-17T15:46:18Z2020-06-17T15:46:18Z

    通常,存在标准算法(并且不仅如此)是为了避免每次手动编写已经以最佳方式编写的代码。如果我们说我们 std::for_each不需要它,那么我们可以成功地说不需要标准算法。毕竟,你总是可以为自己编写一个算法和一个替换标准算法的类……此外 std::for_each,一个仿函数返回它的参数,它可以存储重要信息。您可以手动编写相同的内容,但使用标准算法通常更容易且更可靠(为了避免错误)。在您的具体示例中,我认为没有它更合适。

    ps 另外,集合上的 For-loop 出现的时间比这个算法晚。还有一件事...一个示例,您可以在不使用的情况下使用特定范围std::for_each

    int m[6] = {2, 4, 6, 8, 10, 11};
    for (int& i : m) {
        static size_t k = 0;
        if (k && k <= 3)
            ++i;
        ++k;
    }
    

    根据这个例子,很明显如果序列将由10000元素组成,并且我们需要处理某种小范围,那么我们仍然需要遍历所有元素并每次检查条件,这要昂贵得多而不是std::for_each通过这个特定范围,因此只考虑这个范围

    • 7

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5