小编jam*_*mes的帖子

提高LINQ性能

我有这样的linq语句:

var records = from line in myfile 
              let data = line.Split(',')
              select new { a=int.Parse(data[0]), b=int.Parse(data[1]) };
var average = records.Sum(r => r.b)!=0?records.Sum(r => r.a) / records.Sum(r => r.b):0;
Run Code Online (Sandbox Code Playgroud)

我的问题是:记录的次数是多少次.(r => rb)是在最后一行计算的?LINQ是否每次需要计算总和时都会遍历所有记录(在这种情况下,3 Sum()所以循环3次)?或者只巧妙地循环所有记录一次并计算所有总和?


编辑1:

  1. 我想知道是否有任何方法可以通过仅仅浏览一次所有记录来改进它(因为我们只需要在使用plain for循环时在单个循环中执行它)?

  2. 我们实在没有必要都加载到内存之前,我们能做的总和与平均值.当然,我们可以在从文件加载每个元素时对它们求和.有没有办法减少内存消耗?


编辑2

只是为了澄清一下,在我结束之前我没有使用LINQ.使用plain while/for循环可以实现所有性能要求.但我接着尝试通过使用LINQ来提高可读性并减少代码行.似乎我们无法同时获得两者.

.net c# linq

7
推荐指数
2
解决办法
2414
查看次数

您何时会直接更改std :: vector :: end()?

根据c ++参考vector::end()声明为iterator end() noexcept;(第一种形式)。

这是否意味着我们可以像下面这样直接操作它?

vector<int> v(10);
v.end() = v.begin()+100; // change its end iterator arbitrarily
Run Code Online (Sandbox Code Playgroud)

这可以在clang中很好地编译,但是我怀疑这会导致运行时问题。分段故障?内存泄漏?我不知道。

我的问题是:

  1. 这会引起运行时问题吗?
  2. 首先将其暴露于任意操纵是设计的缺陷吗?
  3. 是否有任何有意义的用例可以直接操作end()迭代器而不引起任何运行时问题?

c++

5
推荐指数
2
解决办法
121
查看次数

为什么C++线程可移动但不可复制?

正如问题标题所说,为什么C++线程(std::threadpthread)是可移动的但不可复制?如果我们确实使其可复制,会产生什么后果?

c++ multithreading pthreads stdthread

4
推荐指数
1
解决办法
2716
查看次数

没有参数的std :: thread构造函数

根据cppreference.com,std::thread没有参数的 构造函数意味着:

创建不代表线程的新线程对象.

我的问题是:

  1. 为什么我们需要这个构造函数?如果我们创建一个thread使用这个构造函数,我们如何在以后"分配"一个线程函数?
  2. 为什么我们没有"run(function_address)"方法,这样当没有参数构造时,我们可以指定一个"运行"的函数thread.
  3. 或者,我们可以构造一个thread带有可调用参数(函数,函子等)但是调用"run()"方法以便稍后实际执行该线程.为什么std::thread不以这种方式设计?

c++ multithreading c++11 stdthread

4
推荐指数
1
解决办法
3512
查看次数

gcc7.3 和 gcc9.3 之间 filesystem::path(filePath).filename() 的不同行为

在 gcc7.3(使用 C++14)和 gcc9.3(使用 C++17)中运行这段代码时,我看到不同的输出:

#include <iostream>
#if (__cplusplus >= 201703L)
    #include <filesystem>
    namespace fs = std::filesystem;
#else
    #include <experimental/filesystem>
    namespace fs = std::experimental::filesystem;
#endif
using namespace std;
std::string getBaseName(const std::string& filePath) {
    return fs::path(filePath).filename().string();
}
int main()
{
    std::cout<<"getBaseName(/test/absolute/dir/)="<<getBaseName("/test/absolute/dir/")<<std::endl;
    std::cout<<"getBaseName(/)="<<getBaseName("/")<<std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在 gcc7.3 (C++14) 中,它给了我:

getBaseName(/test/absolute/dir/)=.
getBaseName(/)=/
Run Code Online (Sandbox Code Playgroud)

在 gcc9.3(C++17) 中,我得到:

getBaseName(/test/absolute/dir/)=
getBaseName(/)=
Run Code Online (Sandbox Code Playgroud)

我想知道这是否是 gcc7.3 中的错误(因此是 std::experimental),如果是,我们是否有任何不依赖任何第三方库的解决方法?

c++ c++14 c++17

3
推荐指数
1
解决办法
70
查看次数

功能模板专业化的别名

int f1(int a, int b) { return a+b; }
int f2(int a, int b) { return a*b; }

template <typename F> void foo(int i, int j)
{
 // do some processing before
 F(i,j);  
 // do some processing after 
}
Run Code Online (Sandbox Code Playgroud)

我想像这样对foo的专业化做一个别名:

constexpr auto foo1 = &foo<f1>;
constexpr auto foo2 = &foo<f2>;
Run Code Online (Sandbox Code Playgroud)

并这样调用函数:foo1(1,2);foo2(1,2); 用C ++可以做到这一点吗?谢谢!


编辑: foo()不是f1的包装,它是一个调用f1或f2的函数。在通话之前和之后,我需要做一些额外的事情。F是一个函子,我想要foo的专业化的“捷径”。上面的代码是伪代码。

c++ alias templates

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

将Microsoft.AspNet.Mvc用于控制台应用程序

我正在编写一个控制台应用程序,我想应用MVC模式.由于ASP.net MVC已经是一个成熟的框架,我想知道我是否可以将它用于我的控制台应用程序,而不是重新发明轮子.

例如,我可以继承Microsoft.AspNet.Mvc.Controller来派生我自己的控制器类吗?

我在Google上做了一些研究,但找不到任何针对这个问题的内容.

c# asp.net-mvc console-application

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

Qt 错误:搜索 -lGL 时跳过不兼容的 /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../libGL.so

Qt 5.7.0 GCC 4.9.1安装 Qt 后 ,我​​创建了一个简单的小部件项目(没有编写任何代码,没有更改设置,只将一些控件拖到表单中)并进行了测试编译。我收到错误消息:

:-1: error: skipping incompatible /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../libGL.so when searching for -lGL
:-1: error: skipping incompatible /lib/libGL.so when searching for -lGL
:-1: error: skipping incompatible /usr/lib/libGL.so when searching for -lGL 
:-1: error: cannot find -lGL
:-1: error: collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

我认为它试图链接到我的 64 位机器中的 32 位 OpenGL。/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../libGL.so 确实位于 /usr/lib/libGL 中。我认为 64 位版本是 /usr/lib64/libGL 中的版本。如何更改链接路径以使其链接到正确的库?

qt qt5

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

使用后自动释放内存

有很多地方我得到这样的代码:

some_function_signature() 
{
    T a;
    T b = f1(a);
    T c = f2(b);
    T d = f3(c);
    ...
}
Run Code Online (Sandbox Code Playgroud)

如您所见,在这样的函数中,a传递f1()给生成b,然后b传递f2()给生成c,等等.函数调用(f1,f2,f3...)后不会使用这些变量.并且它们拥有大容量存储器(例如,T是大图像数据).这里的问题是在这个函数中,累积的内存消耗可能很大,我想减少它.等待T的析构函数释放内存将使峰值内存使用量some_function_signature()非常大.

我可以做这样的事情来使用后释放内存:

some_function_signature() 
{
    T a;
    T b = f1(a); a.free();
    T c = f2(b); b.free();
    T d = f3(c); c.free();
    ...
}
Run Code Online (Sandbox Code Playgroud)

我想知道我是否可以使这个过程自动且更优雅.例如,作用域内存管理过程或使用类型的引用计数,但我只是不知道如何最好地应用这些方法.

c++ memory-management c++11

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

当我们已经有一个通知变量时,为什么要使用condition_variable?

请考虑以下代码:

int main() { 
    bool done = false; 
    condition_variable con;
    mutex m;

    thread producer([&]() {
        this_thread::sleep_for(chrono::seconds(10)); 
        done = true;
        //con.notify_one();
    });

    thread consumer([&]() {
        /*unique_lock<mutex> lock(m);
        while (!done) {
            con.wait(lock);
        }*/
        while (!done);
        cout << "now my turn..."<<endl;
    });

    producer.join();
    consumer.join(); 
}
Run Code Online (Sandbox Code Playgroud)

如果我取消注释2个线程中的代码,我将使用condition_variable.所以消费者线程看起来像这样:

thread consumer([&]() {
    unique_lock<mutex> lock(m);
    while (!done) {
        con.wait(lock);
    } 
    // while (!done); <-this is equivalent of the above
    cout << "now my turn..."<<endl;
});
Run Code Online (Sandbox Code Playgroud)

似乎我可以使用/不使用condition_variable来实现相同的功能.所以我的问题是:如果已经使用了通知变量(在这种情况下为'done'变量),为什么我们需要condition_variable?使用它有什么好处?我可以做一些通知变量不能做的事吗?

c++ multithreading condition-variable

0
推荐指数
1
解决办法
186
查看次数