我目前正在做一个项目,我需要在 vector 中存储相当多(约数十亿个单位)的结构。我还需要以线性方式迭代该 vector ,因此我需要处理的数据越少越好。
于是自然而然的开始优化单体结构的尺寸。例如,如果我有多个 bool 值,我可以将 true/false 值存储在一个位中,并将所有 bool 值压缩到一个 char/16 位中,无论大小是否足够。对于某些条目,我只需要 20 位无符号整数。因此我可以再次压缩这些值。
然后我得到这样的结果(请注意,这只是简化的示例):
class Foo {
private:
uint32_t m_time;
uint32_t m_comb;
public:
Foo(uint32_t t, uint32_t big, uint16_t small, bool is_blue, bool is_nice)
: m_time(t), m_comb((big << 12) | (small << 2) | (is_blue << 1) | is_nice)
{ }
uint32_t get_time() const { return m_time; }
uint32_t get_big() const { return m_comb >> 12; }
uint16_t get_small() const { return m_comb & 0b11111111100; }
uint16_t is_blue() const { return m_comb & 0b10; }
uint16_t is_nice() const { return m_comb & 0b1; }
};
问题是,这是否可以使用模板以某种方式自动化?我的想法是,我将插入条目的顺序、所需的位大小,然后我将能够调用 get<i>()这将返回结构的第 i 个条目。我的动机是摆脱手动编写代码,因为在我看来,挠痒痒的部分很容易出错。我试图自己实现这一点,但无可救药地失败了。
最佳答案
您可以使用 bit fields 轻松实现这一点.
class Foo {
private:
uint32_t m_time;
uint32_t m_big : 20;
uint32_t m_small : 10;
uint32_t m_isblue : 1;
uint32_t m_isnice : 1;
public:
Foo(uint32_t t, uint32_t big, uint16_t small, bool is_blue, bool is_nice)
: m_time(t), m_big(big), m_small(small), m_isblue(is_blue), m_isnice(is_nice)
{ }
uint32_t get_time() const { return m_time; }
uint32_t get_big() const { return m_big; }
uint16_t get_small() const { return m_small; }
uint16_t is_blue() const { return m_isblue; }
uint16_t is_nice() const { return m_isnice; }
};
Online demo显示大小。
编辑:附加信息
总结评论,编译器将位字段打包在一起的方式取决于实现:
9.6/1 (...) Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined. Bit-fields are packed into some addressable allocation unit. [Note: Bit-fields straddle allocation units on some machines and not on others. Bit-fields are assigned right-to-left on some machines, left-to-right on others. —end note ]
因此您无法保证,但编译器通常会尽力将它们放在一起。根据经验,只要您的位字段是连续的并且它们的总位数小于您使用的基本类型,那么打包很可能是最佳的。如果需要,您可以微调基本类型,如 this online demo显示。
关于c++ - 位压缩结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37067810/
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
您将如何构建一个简单的Sinatra应用程序?我正在制作,我希望该应用具有以下功能:“应用程序”更像是一个包含所有信息的管理仪表板。然后另一个应用程序将通过REST访问信息。我还没有创建仪表板,只是从数据库中获取东西session和身份验证(尚未实现)您可以上传图片,其他应用可以显示这些图片我已经使用RSpec创建了一个测试文件通过Prawn生成报告目前的设置是这样的:app.rbtest_app.rb因为我实际上只有应用程序和测试文件。到目前为止,我已经将Datamapper用于ORM,将SQLite用于数据库。这是我的第一个Ruby/Sinatra项目,所以欢迎任何和所有建议-我应
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
是否有任何可用于Ruby的开源压缩/解压库?有没有人实现过LZW?或者,是否有任何使用压缩组件的开源库可以提取出来独立使用?编辑——感谢您的回答!我应该提到我必须压缩的是只驻留在数据库中的长字符串(我不会压缩文件)。此外,如果可以执行此操作的任何库都具有用于客户端压缩/分解的等效JavaScript实现,那将是理想的,因为这将用于Web应用程序。 最佳答案 您会在rubystdlib下找到所有已交付的ruby库的一个很好的列表.我会使用zlib库,它是开放的,无处不在,您会发现几乎所有语言的库!
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
我想编写一个ruby脚本来递归复制目录结构,但排除某些文件类型。因此,给定以下目录结构:folder1folder2file1.txtfile2.txtfile3.csfile4.htmlfolder2folder3file4.dll我想复制这个结构,但不包含.txt和.cs文件。因此,生成的目录结构应如下所示:folder1folder2file4.htmlfolder2folder3file4.dll 最佳答案 您可以使用查找模块。这是一个代码片段:require"find"ignored_extensions=[".cs"