我有两个这样的性能关键函数:
insertExpensive(Holder* holder, Element* element, int index){
//............ do some complex thing 1
holder->ensureRange(index);//a little expensive
//............ do some complex thing 2
}
insertCheap(Holder* holder, Element* element, int index){
//............ do some complex thing 1
//............ do some complex thing 2
}
如何将 2 个函数组合在一起以提高可维护性?
解决方案 1.
insertExpensive(Holder* holder, Element* element, int index){
do1();
holder->ensureRange(index);//a little expensive
do2();
}
insertCheap(Holder* holder, Element* element, int index){
do1();
do2();
}
那会很丑。
如果 do2 想要来自 do1 的一些局部变量,这也是不切实际的。
解决方案 2.
insert(Holder* holder, Element* element, int index, bool check){
//............ do some complex thing 1
if(check)holder->ensureRange(index);//a little expensive
//............ do some complex thing 2
}
每次调用都需要进行条件检查。
解决方案 3.(草稿)
template<bool check> insert(Holder* holder, Element* element, int index){
//............ do some complex thing 1 (Edit2 from do1());
bar<check>();
//............ do some complex thing 2 (Edit2 from do2());
}
template <>
inline void base_template<true>::bar() { holder->ensureRange(index); }
template <>
inline void base_template<false>::bar() { }
矫枉过正和不必要的复杂性?
编辑 1:
衡量方法好坏的标准优先级排序如下:-
1.最佳表现
2.减少重复代码
3. 代码总行少
4. 更易于专家和初学者阅读
编辑 2: 编辑第三个解决方案。感谢 mvidelgauz 和 Wolf。
最佳答案
您的解决方案 2 实际上还没有那么糟糕。如果此代码在 header 内,则它被隐式视为内联代码。 (我明确地写了它)如果你用 true 或 false 调用它,编译器可以删除 if 语句,尽管它是否会这样做取决于一系列因素。 (内联后的全身大小,常量的可见性,调优...)
inline void insert(Holder* holder,Element* element,int index, bool check){
do1();
if (check)
holder->ensureRange(index);//a little expensive
do2();
}
解决方案 3 实际上是您想要实现的,因为模板需要为每个不同的调用进行新的函数实例化,因此它会删除死代码。但是,它的编写方式与您编写解决方案 2 的方式非常相似。
template <bool check>
inline void insert(Holder* holder,Element* element,int index){
do1();
if (check)
holder->ensureRange(index);//a little expensive
do2();
}
如果你有 C++17,你不再需要依赖编译器来删除死代码,因为你可以强制它通过 constexpr-if 跳过某些代码。这种构造将保证 if 语句中的代码被删除,因为它甚至不必编译。
template <bool check>
inline void insert(Holder* holder,Element* element,int index){
do1();
if constexpr (check)
holder->ensureRange(index);//a little expensive
do2();
}
关于c++ - 将仅 1 行代码不同的两个函数分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38812275/
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的