小编Yak*_*ont的帖子

快速进行字符串搜索

我有一个问题,我正在寻找一些指导来解决最有效的方法.我有2亿个数据字符串,大小从3个字符到70个字符不等.字符串由字母数字和几个特殊字符组成,如短划线和下划线.我需要能够快速搜索整个字符串或字符串中的任何子字符串(最小子字符串大小为3).这里快速定义为不到1秒.

作为我的第一次切入,我做了以下事情:

  1. 创建了38个索引文件.索引包含以特定字母开头的所有子字符串.第一个4mb包含100万个散列桶(哈希链的开始).索引的其余部分包含来自散列桶的链接列表链.我的散列分布非常均匀.100万个散列桶保存在RAM中并镜像到磁盘.

  2. 当一个字符串被添加到索引时,它被分解为其非重复的(在其自身内)3-n字符子串(当n是字符串-1的长度时).因此,例如,"apples"作为pples,pple,ppl,pp存储在"A"索引中(子串也存储在"L"和"P"索引中).

搜索/添加服务器作为守护进程运行(在C++中)并且像冠军一样运行.典型的搜索时间不到1/2秒.

问题出在流程的前端.我通常一次添加30,000个密钥.这部分过程需要永远.通过基准测试,将180,000个可变长度键的空索引的加载时间约为3 1/2小时.

除了很长的加载时间外,该方案有效.

在我坚持优化(或尝试)之前,我想知道是否有更好的方法来解决这个问题.前面和后面的通配符搜索(即:DBMS中的'%ppl%'字符串非常慢(例如MySQL的小时数)对于这么大的数据集.所以看起来DBMS解决方案是不可能的.我不能使用全文搜索,因为我们不是处理普通单词,而是可能或可能不是由真实单词组成的字符串.

c++ search

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

构造函数继承的虚拟继承

我有一个类层次结构,归结为

class Module { };

struct Port {
    Module& owner;
    Port(Module& owner) : owner(owner) {}
};

struct InPort    : virtual Port    { using Port::Port; };
struct OutPort   : virtual Port    { using Port::Port; };
struct InOutPort : InPort, OutPort { using Port::Port; };
Run Code Online (Sandbox Code Playgroud)

如您所见,我更愿意创建一些基本功能,并以经典的菱形图案继承它.我也想使用构造函数继承使其尽可能地证明未来...

但是,这不起作用如上所述

prog.cpp: In function 'int main()':
prog.cpp:14:15: error: use of deleted function 'InOutPort::InOutPort(Module&)'
  InOutPort p(m);
Run Code Online (Sandbox Code Playgroud)

InOutPort使用更明确的版本替换定义也是不够的:

struct InOutPort : InPort, OutPort { InOutPort(Module& m) : Port(m), InPort(m), OutPort(m) { } }; …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance virtual-inheritance c++11

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

如何在Autoconf中使用C++ 11功能?

我有一个通过Autoconf配置的项目,我想在这个项目中开始使用C++ 11功能.如何始终启用"-std = gnu ++ 0x"开关并支持配置时检查的功能?

c++ autoconf c++11

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

你如何将std :: system_error与GetLastError一起使用?

如果我调用通过GetLastError报告错误的Win32函数,例如RegisterClassEx,如何为该错误抛出std :: system_error?

c++ winapi c++11

13
推荐指数
2
解决办法
5820
查看次数

为什么条件变量会修复我们的功耗?

我们正在使用Mac上的音频播放器项目,并注意到电源使用率非常高(约为google chrome执行相同工作负载的7倍).

我使用了xcode的能量分析工具,其中一个问题是我们有太多的CPU唤醒开销.

根据xcode:

每次CPU从空闲状态唤醒时,都会产生能量损失.如果唤醒很高,并且每次唤醒的CPU利用率很低,那么您应该考虑批处理工作.

我们已经将问题缩小到了一个usleep函数调用.

在我们的代码中,音频解码器是一个生产音频数据并将其插入消费者的生产者 - 音频播放器.我们的音频播放器基于OpenAL,它具有音频数据缓冲区.

因为音频播放器可能比生产者慢,所以我们总是在向音频播放器提供新的音频数据之前检查缓冲器的可用性.如果没有可用的缓冲区,我们会暂停一段时间再试一次.所以代码看起来像:

void playAudioBuffer(Data *data)
{
    while(no buffer is available)
    {
         usleep()
    }
    process data.
}
Run Code Online (Sandbox Code Playgroud)

知道usleep是一个问题,我们做的第一件事就是删除usleep().(因为OpenAL似乎不提供回调或任何其他方式,轮询似乎是唯一的选择.)我们成功地将功耗降低了一半.

然后,昨天,我们尝试了

for(int i =0; i<attempts; ++i)
{
    std::unique_lock<std::mutex> lk(m);
    cv.wait_for(lk, 3, []{
                            available = checkBufferAvailable(); 
                            return available;
                         })

    if (available)
    {
         process buf;
    }
 }
Run Code Online (Sandbox Code Playgroud)

这是我们偶然尝试的一项实验.它对我们来说没有任何意义,因为逻辑上它执行相同的等待.并且条件变量的使用不正确,因为变量"available"只能由一个线程访问.但它实际上减少了90%的能耗,线程的CPU使用量下降了很多.现在我们比铬更好.但条件变量如何实现与以下代码不同?为什么它会节省我们的力量?

mutex lock;
while(condition is false)
{
    mutex unlock;
    usleep();
    mutex lock;
}
...
mutex unlock
...
Run Code Online (Sandbox Code Playgroud)

(我们使用mac的活动监视器(能量编号)和cpu使用情况分析工具来测量能耗.)

c++ energy condition-variable thread-sleep

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

如何返回指针(和所有权)的向量C++ 11

我有一个工厂方法,它创建一堆对象并返回指向它们的指针.对象的所有权转移给调用者:

std::vector<animal*> create_zoo();
Run Code Online (Sandbox Code Playgroud)

这有效,但容易出现内存泄漏.

auto zoo = create_zoo();
Run Code Online (Sandbox Code Playgroud)

向量在堆栈上并自动清理,包含的对象不是.

返回各种子类型的对象.撤消值而不是指针是行不通的.

我在考虑使用

std::vector<std::unique_ptr<animal> > create_zoo();
Run Code Online (Sandbox Code Playgroud)

但是unique_ptr没有复制语义,我返回了vectorby值,理论上它创建了一个副本.

我可以放在vector堆上以避免这种情况

std::unique_ptr<std::vector<std::unique_ptr<animal> > > create_zoo();
Run Code Online (Sandbox Code Playgroud)

但这太荒谬了.

这也应该有效:

std::vector<std::shared_ptr<animal> > create_zoo();
Run Code Online (Sandbox Code Playgroud)

这可行,但它并没有真正转移所有权.调用者必须假设可能有其他指向对象的指针.

我愿意接受建议.不需要std::vector.我只是在寻找一种实现工厂的好方法,该工厂使用现代c ++返回多个对象的所有权.我现在正在避免提振.我正在尝试探索新的c ++ 11内容.

c++ pointers smart-pointers vector c++11

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

C++ 11 to_string()函数,在哪里?

请参阅N3242 C++ 11工作草案,第21.5章"数字转换".

有一些有用的功能,string to_string(int val);如上所述,但我不明白它们是如何调用的.谁能给我一个例子吗?

c++ c++11

12
推荐指数
2
解决办法
2万
查看次数

nullptr vs __nullptr

我只是想知道为什么有两种方法来指定空指针.我一直在浏览这个链接,但没有清楚地了解它的用途.

有人可以举出什么时候使用什么的好例子吗?

c++ c++-cli c++11

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

MinGW的C++ 11功能

我尝试将emplace()函数用于unordered_map,编译器说没有这样的函数存在.

我说-std=c+11,它说cc1plus.exe: error: unrecognized command line option '-std=c+11'

我可以以某种方式使用mingw的C++ 11功能吗?

c++ windows mingw c++11

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

如何在std :: function的签名上重载构造函数?

我正在尝试编写一个带有重载构造函数的类,它接受std :: function对象作为参数,但当然每个该死的东西都可以隐式地转换为任何签名的std :: function.这自然是非常有用的.

例:

class Foo {
  Foo( std::function<void()> fn ) {
    ...code...
  }
  Foo( std::function<int()> fn ) {
    ...code...
  }
};

Foo a( []() -> void { return; } );    // Calls first constructor
Foo b( []() -> int { return 1; } );   // Calls second constructor
Run Code Online (Sandbox Code Playgroud)

这将无法编译,抱怨两个构造函数基本相同且含糊不清.当然,这是无稽之谈.我尝试过enable_if,is_same和其他一些东西.接受函数指针是不可能的,因为这会阻止有状态lambda的传递.当然必须有办法实现这一目标吗?

我害怕,我的模板技能有点缺乏.普通的模板类和函数很容易,但使用编译器玩傻傻的玩家有点超出了我的联盟.有人可以帮帮我吗?

我之前已经知道这个问题的变体,但它们通常关注的是正常的函数而不是构造函数; 或者通过参数而不是返回类型进行重载.

c++ lambda constructor overloading c++11

12
推荐指数
2
解决办法
644
查看次数