d**d 发帖数: 389 | 1 问题是这样的:
有一段二进制数据,格式是6中格式中的一种。以前我是用C写了6个不同的decoder,每
个decoder给主程序提供一个回调函数和一个解码函数。主程序就是把数据的开头的一
段送给每个decoder的回调函数来验证一下是不是当前decoder能解码的。如果是的话就
调用解码函数来从头处理所有的数据。这个机制目前工作的很好。
现在的问题是有一个新的项目也是要处理相同的问题,但是需要的decoder更多,大约
需要20几个,大大老板昨天发了一封信说所有的decoder要全部用C++来写。我的思路就
被以前的思路给限制住了,感觉没有什么好的办法来解决这个查找decoder的问题。发
到这里来问问,看看有什么好的办法用C++来解决。非常感谢!!!! |
n****j 发帖数: 1708 | 2 不管用什么写,都得把数据开头送给 decoder,除非数据包头有 magic code 能节省一
点时间,否则 c++ 和 c 没区别。
【在 d**d 的大作中提到】 : 问题是这样的: : 有一段二进制数据,格式是6中格式中的一种。以前我是用C写了6个不同的decoder,每 : 个decoder给主程序提供一个回调函数和一个解码函数。主程序就是把数据的开头的一 : 段送给每个decoder的回调函数来验证一下是不是当前decoder能解码的。如果是的话就 : 调用解码函数来从头处理所有的数据。这个机制目前工作的很好。 : 现在的问题是有一个新的项目也是要处理相同的问题,但是需要的decoder更多,大约 : 需要20几个,大大老板昨天发了一封信说所有的decoder要全部用C++来写。我的思路就 : 被以前的思路给限制住了,感觉没有什么好的办法来解决这个查找decoder的问题。发 : 到这里来问问,看看有什么好的办法用C++来解决。非常感谢!!!!
|
d**d 发帖数: 389 | 3 不考虑性能的问题,现在的问题是怎么来设计C++ class来解决这个查找decoder的的问
题。
基本上是有一个interface class,然后各个decoder来实例这个interface,但是怎么让
主程序来查找哪个decoder能用了解码的问题,我就没有头绪了。
【在 n****j 的大作中提到】 : 不管用什么写,都得把数据开头送给 decoder,除非数据包头有 magic code 能节省一 : 点时间,否则 c++ 和 c 没区别。
|
d****n 发帖数: 12461 | 4 把decoder试错的顺序按照数据的频率从高到低排序就可以了。水平高的再搞个动态的
排序。
写程序逻辑越简单越好。
【在 d**d 的大作中提到】 : 问题是这样的: : 有一段二进制数据,格式是6中格式中的一种。以前我是用C写了6个不同的decoder,每 : 个decoder给主程序提供一个回调函数和一个解码函数。主程序就是把数据的开头的一 : 段送给每个decoder的回调函数来验证一下是不是当前decoder能解码的。如果是的话就 : 调用解码函数来从头处理所有的数据。这个机制目前工作的很好。 : 现在的问题是有一个新的项目也是要处理相同的问题,但是需要的decoder更多,大约 : 需要20几个,大大老板昨天发了一封信说所有的decoder要全部用C++来写。我的思路就 : 被以前的思路给限制住了,感觉没有什么好的办法来解决这个查找decoder的问题。发 : 到这里来问问,看看有什么好的办法用C++来解决。非常感谢!!!!
|
d**d 发帖数: 389 | 5 写20几个if/else? 不会吧?
【在 d****n 的大作中提到】 : 把decoder试错的顺序按照数据的频率从高到低排序就可以了。水平高的再搞个动态的 : 排序。 : 写程序逻辑越简单越好。
|
g*****y 发帖数: 7271 | 6 每个decoder register一下,然后loop就好。扩展decoder就很容易了。
【在 d**d 的大作中提到】 : 写20几个if/else? 不会吧?
|
d**d 发帖数: 389 | 7 这个就是我一开用C的写法,每个decoder去主程序register一下回调函数和解码函数。
对于C++,我原先想的是如果每个decoder的class都定义一个static的格式判断函数和
static decoder* geInstance(),然后都在主程序登记一下。主程序还是用loop来调用
每一个decoder的格式判断函数,如果是正确的格式,再调用getInstance(),然后调用
解码函数。这样的话用C++类的写法也没有太多的优势。
还是有更好的设计方法和思路?
【在 g*****y 的大作中提到】 : 每个decoder register一下,然后loop就好。扩展decoder就很容易了。
|
k***g 发帖数: 166 | 8 可以用hash对数据头生成一个数,然后直接调用对应的decoder,省去20几次判断了
C++面向对象的特性感觉这种场景用不上
【在 d**d 的大作中提到】 : 问题是这样的: : 有一段二进制数据,格式是6中格式中的一种。以前我是用C写了6个不同的decoder,每 : 个decoder给主程序提供一个回调函数和一个解码函数。主程序就是把数据的开头的一 : 段送给每个decoder的回调函数来验证一下是不是当前decoder能解码的。如果是的话就 : 调用解码函数来从头处理所有的数据。这个机制目前工作的很好。 : 现在的问题是有一个新的项目也是要处理相同的问题,但是需要的decoder更多,大约 : 需要20几个,大大老板昨天发了一封信说所有的decoder要全部用C++来写。我的思路就 : 被以前的思路给限制住了,感觉没有什么好的办法来解决这个查找decoder的问题。发 : 到这里来问问,看看有什么好的办法用C++来解决。非常感谢!!!!
|
b*******s 发帖数: 5216 | 9 trie, only if headers are really heavy burden to analysis |
b*******s 发帖数: 5216 | 10 or a chain of functions for detecting, so you only have to parse the header
once |
|
|
b*******s 发帖数: 5216 | 11 the essence of this thing is a kind of parser |
w***g 发帖数: 5958 | 12 我有个项目跟你这个有点像。接受HTTP上传的一个二进制对象,
然后用libmagic检测对象MIME。每个支持的对象都有一个类(Tagger)进行识别。
然后维护一个map字典把MIME字符串映射到不同的Tagger实现。
https://github.com/aaalgo/stags/blob/master/src/stags.h
C++最恶心的是各种decoder没法自动register,得手工加一行才行。
如果要自动register,得每个decoder编译成一个.so文件,然后启动的时候
扫描plugin目录加载所有的.so文件。
还有一个办法就是约定命名规则,凡是symbol name match某pattern的就认为
是一个decoder。然后程序起动后扫描symbol table,(dlopen传入NULL则是
open程序自己)。这种做法可以把所有的东西全都编译成一个可执行文件。
不过我没见人用过这种方法。相比之下往初始化函数里加一行要容易得多。
【在 d**d 的大作中提到】 : 问题是这样的: : 有一段二进制数据,格式是6中格式中的一种。以前我是用C写了6个不同的decoder,每 : 个decoder给主程序提供一个回调函数和一个解码函数。主程序就是把数据的开头的一 : 段送给每个decoder的回调函数来验证一下是不是当前decoder能解码的。如果是的话就 : 调用解码函数来从头处理所有的数据。这个机制目前工作的很好。 : 现在的问题是有一个新的项目也是要处理相同的问题,但是需要的decoder更多,大约 : 需要20几个,大大老板昨天发了一封信说所有的decoder要全部用C++来写。我的思路就 : 被以前的思路给限制住了,感觉没有什么好的办法来解决这个查找decoder的问题。发 : 到这里来问问,看看有什么好的办法用C++来解决。非常感谢!!!!
|
y*****r 发帖数: 327 | 13 这就是一简单的factory pattern。 |
w***g 发帖数: 5958 | 14 标准实现是啥?
【在 y*****r 的大作中提到】 : 这就是一简单的factory pattern。
|
d**d 发帖数: 389 | 15 对,就是这样的问题。我不想去扫描plugin目录,太麻烦。就是直接把所有的decoder
放进一个so文件里面。
【在 w***g 的大作中提到】 : 我有个项目跟你这个有点像。接受HTTP上传的一个二进制对象, : 然后用libmagic检测对象MIME。每个支持的对象都有一个类(Tagger)进行识别。 : 然后维护一个map字典把MIME字符串映射到不同的Tagger实现。 : https://github.com/aaalgo/stags/blob/master/src/stags.h : C++最恶心的是各种decoder没法自动register,得手工加一行才行。 : 如果要自动register,得每个decoder编译成一个.so文件,然后启动的时候 : 扫描plugin目录加载所有的.so文件。 : 还有一个办法就是约定命名规则,凡是symbol name match某pattern的就认为 : 是一个decoder。然后程序起动后扫描symbol table,(dlopen传入NULL则是 : open程序自己)。这种做法可以把所有的东西全都编译成一个可执行文件。
|
d**d 发帖数: 389 | 16 我觉得要是用factory pattern来做的话,factory需要去分析header,然后从分析结果
里面来决定产生哪个decoder。这样的话实际上是把decoder的分析工作放到了factory
里面。将来如果还要加新的decoder的话,还要去改factory那方面的代码,不好维护。
不知道是不是你有更好的想法?
【在 y*****r 的大作中提到】 : 这就是一简单的factory pattern。
|
p******g 发帖数: 347 | 17 扫描目录有什么难得。直接用boost。 你 dlopen 一个和多个 so 有什么区别?
或者你写一个配置文件里面列出来所有的decoder function 的名字, 所在的so文件。
程序加载的时候就毒一下这个文件dlopen 然后找到所有的decoder集中放一起就完了。
这个问题和c艹 真的没啥关系。c/c艹 没什么大区别
decoder
【在 d**d 的大作中提到】 : 对,就是这样的问题。我不想去扫描plugin目录,太麻烦。就是直接把所有的decoder : 放进一个so文件里面。
|
p******g 发帖数: 347 | 18 你的各个decoder还是用c写放在一个或者多个so库里。不同的decoder之间没有关联就
不要硬放到一起。
你把所有的decoder c 函数动态找到以后可以放到一起集中保存到一个类里叫他
SuperDecoder。每个c decoder分配一个结果buffer/queue。然后分析选择头文件的时
候可以并发多个线程所有的decoder一起做,那个成功就一直执行到底,不成功的就早
早返回一个无效结果。你的SuperDecoder就负责从所有的buffer poll 有效结果就好了。
【在 d**d 的大作中提到】 : 这个就是我一开用C的写法,每个decoder去主程序register一下回调函数和解码函数。 : 对于C++,我原先想的是如果每个decoder的class都定义一个static的格式判断函数和 : static decoder* geInstance(),然后都在主程序登记一下。主程序还是用loop来调用 : 每一个decoder的格式判断函数,如果是正确的格式,再调用getInstance(),然后调用 : 解码函数。这样的话用C++类的写法也没有太多的优势。 : 还是有更好的设计方法和思路?
|
y*****r 发帖数: 327 | 19 factory code is something like
Decoder * decode(char* data){
for(int i = 0; i < m_decoders.size(); ++i)
if(m_decoders[i]->decode(data)) return m_decoders[i];
return null;
}
you just need to add all decoders to m_decoders at beginning.
factory
【在 d**d 的大作中提到】 : 我觉得要是用factory pattern来做的话,factory需要去分析header,然后从分析结果 : 里面来决定产生哪个decoder。这样的话实际上是把decoder的分析工作放到了factory : 里面。将来如果还要加新的decoder的话,还要去改factory那方面的代码,不好维护。 : 不知道是不是你有更好的想法?
|
N*****m 发帖数: 42603 | 20 Java做很简单
c++没有reflection,所以得自己手动搞
factory
【在 d**d 的大作中提到】 : 我觉得要是用factory pattern来做的话,factory需要去分析header,然后从分析结果 : 里面来决定产生哪个decoder。这样的话实际上是把decoder的分析工作放到了factory : 里面。将来如果还要加新的decoder的话,还要去改factory那方面的代码,不好维护。 : 不知道是不是你有更好的想法?
|
|
|
g*****y 发帖数: 7271 | 21 你可以看一下那个所谓的pluggable factories。可以看下面这个link
https://adtmag.com/articles/2000/09/25/industrial-strength-plug
factories.aspx
对于你这个问题,如果不会很复杂的话,应该没必要搞那么复杂。
C还是C++差别不会很大。
【在 d**d 的大作中提到】 : 这个就是我一开用C的写法,每个decoder去主程序register一下回调函数和解码函数。 : 对于C++,我原先想的是如果每个decoder的class都定义一个static的格式判断函数和 : static decoder* geInstance(),然后都在主程序登记一下。主程序还是用loop来调用 : 每一个decoder的格式判断函数,如果是正确的格式,再调用getInstance(),然后调用 : 解码函数。这样的话用C++类的写法也没有太多的优势。 : 还是有更好的设计方法和思路?
|
g*****y 发帖数: 7271 | 22 自动registering的办法有不少讨论。随便狗了一个。不知道好用不。
https://hewjunwei.wordpress.com/2013/02/26/self-registering-obj
factories/
【在 w***g 的大作中提到】 : 我有个项目跟你这个有点像。接受HTTP上传的一个二进制对象, : 然后用libmagic检测对象MIME。每个支持的对象都有一个类(Tagger)进行识别。 : 然后维护一个map字典把MIME字符串映射到不同的Tagger实现。 : https://github.com/aaalgo/stags/blob/master/src/stags.h : C++最恶心的是各种decoder没法自动register,得手工加一行才行。 : 如果要自动register,得每个decoder编译成一个.so文件,然后启动的时候 : 扫描plugin目录加载所有的.so文件。 : 还有一个办法就是约定命名规则,凡是symbol name match某pattern的就认为 : 是一个decoder。然后程序起动后扫描symbol table,(dlopen传入NULL则是 : open程序自己)。这种做法可以把所有的东西全都编译成一个可执行文件。
|
g*****y 发帖数: 7271 | 23 这和reflection没什么关系吧?
很多tricks其实就是share factory code或者自动registering之类的。
大多数都是利用template来搞。不知道Java的template好用不,
从来没有试过。
【在 N*****m 的大作中提到】 : Java做很简单 : c++没有reflection,所以得自己手动搞 : : factory
|
g*****y 发帖数: 7271 | 24 是factory pattern。分析部分通过调用每个decoder提供的callback就好。
factory的code相对很稳定,不用怎么改。就是所谓的pluggable factory了。
factory
【在 d**d 的大作中提到】 : 我觉得要是用factory pattern来做的话,factory需要去分析header,然后从分析结果 : 里面来决定产生哪个decoder。这样的话实际上是把decoder的分析工作放到了factory : 里面。将来如果还要加新的decoder的话,还要去改factory那方面的代码,不好维护。 : 不知道是不是你有更好的想法?
|
N*****m 发帖数: 42603 | 25 楼上说的是不想把header->decoder hardcoded
如果有reflection,直接用个property file定义,runtime load就好了
【在 g*****y 的大作中提到】 : 这和reflection没什么关系吧? : 很多tricks其实就是share factory code或者自动registering之类的。 : 大多数都是利用template来搞。不知道Java的template好用不, : 从来没有试过。
|
g*****y 发帖数: 7271 | 26 这就是register新的decoder的部分吧?C/C++也不用改code啊,
如果是dll的话,只要把新的decoder的dll放到指定目录,
就可以自动load了。
如果静态连接,新decoder的文件里需要register它自己。
不用改别的文件。有很多通过继承来完成自动register的
做法。reflection在这上面没什么优势吧。
【在 N*****m 的大作中提到】 : 楼上说的是不想把header->decoder hardcoded : 如果有reflection,直接用个property file定义,runtime load就好了
|
N*****m 发帖数: 42603 | 27 load decoders不是问题
问题是怎么不用重新编译,把header跟decoder对应起来
【在 g*****y 的大作中提到】 : 这就是register新的decoder的部分吧?C/C++也不用改code啊, : 如果是dll的话,只要把新的decoder的dll放到指定目录, : 就可以自动load了。 : 如果静态连接,新decoder的文件里需要register它自己。 : 不用改别的文件。有很多通过继承来完成自动register的 : 做法。reflection在这上面没什么优势吧。
|
g*****y 发帖数: 7271 | 28 照我理解,以dll办法为例:
1. 所有找到的某个目录下的decoder dlls,加入链表;
2. 把header依次传给decoder的回调函数来分析header并返回是否接受;
3. 如果某一个decoder回调函数返回接受,就把数据传给该decoder的
decode回调函数;
分析header的回调函数是decoder来implement的。新decoder
的code当然需要编译成dll。除了这个,还有什么要重新编译的么?
哪个语言里新的decoder都要重新编译吧?
【在 N*****m 的大作中提到】 : load decoders不是问题 : 问题是怎么不用重新编译,把header跟decoder对应起来
|
N*****m 发帖数: 42603 | 29 你这个第二步太低效了,30个decoders你一个个试开销太大了
【在 g*****y 的大作中提到】 : 照我理解,以dll办法为例: : 1. 所有找到的某个目录下的decoder dlls,加入链表; : 2. 把header依次传给decoder的回调函数来分析header并返回是否接受; : 3. 如果某一个decoder回调函数返回接受,就把数据传给该decoder的 : decode回调函数; : 分析header的回调函数是decoder来implement的。新decoder : 的code当然需要编译成dll。除了这个,还有什么要重新编译的么? : 哪个语言里新的decoder都要重新编译吧?
|
r*g 发帖数: 186 | 30 看了一下问题本身
感觉这个东西并不是哪里不可完成
难度主要在体力上吧?
或者我简单化了某些问题
总之我觉得越简单越好
【在 d**d 的大作中提到】 : 问题是这样的: : 有一段二进制数据,格式是6中格式中的一种。以前我是用C写了6个不同的decoder,每 : 个decoder给主程序提供一个回调函数和一个解码函数。主程序就是把数据的开头的一 : 段送给每个decoder的回调函数来验证一下是不是当前decoder能解码的。如果是的话就 : 调用解码函数来从头处理所有的数据。这个机制目前工作的很好。 : 现在的问题是有一个新的项目也是要处理相同的问题,但是需要的decoder更多,大约 : 需要20几个,大大老板昨天发了一封信说所有的decoder要全部用C++来写。我的思路就 : 被以前的思路给限制住了,感觉没有什么好的办法来解决这个查找decoder的问题。发 : 到这里来问问,看看有什么好的办法用C++来解决。非常感谢!!!!
|
|
|
x****u 发帖数: 44466 | 31 如果用dll自然是直接做成com组件了,所有的坑ms都帮你踩过几百遍了。
【在 g*****y 的大作中提到】 : 照我理解,以dll办法为例: : 1. 所有找到的某个目录下的decoder dlls,加入链表; : 2. 把header依次传给decoder的回调函数来分析header并返回是否接受; : 3. 如果某一个decoder回调函数返回接受,就把数据传给该decoder的 : decode回调函数; : 分析header的回调函数是decoder来implement的。新decoder : 的code当然需要编译成dll。除了这个,还有什么要重新编译的么? : 哪个语言里新的decoder都要重新编译吧?
|
T********i 发帖数: 2416 | 32 别听那些人扯淡。
20个decoder算个屁?就用if then else。啥pluggable dll都是扯淡。你又不支持第三
方plugin。而且貌似就你一个干活的,连个大team都没有。有必要设计那么复杂的
contract么?
dll不是光expose api那么简单,还要处理复杂数据结构。尤其是c++。那是dll hell。
每次都要编译20多个target,纯粹没事找事。
20个if then else,开销是纳秒级别。而且绝对代码最少,出错可能性最小,我打赌不
会有任何性能问题。
【在 d**d 的大作中提到】 : 问题是这样的: : 有一段二进制数据,格式是6中格式中的一种。以前我是用C写了6个不同的decoder,每 : 个decoder给主程序提供一个回调函数和一个解码函数。主程序就是把数据的开头的一 : 段送给每个decoder的回调函数来验证一下是不是当前decoder能解码的。如果是的话就 : 调用解码函数来从头处理所有的数据。这个机制目前工作的很好。 : 现在的问题是有一个新的项目也是要处理相同的问题,但是需要的decoder更多,大约 : 需要20几个,大大老板昨天发了一封信说所有的decoder要全部用C++来写。我的思路就 : 被以前的思路给限制住了,感觉没有什么好的办法来解决这个查找decoder的问题。发 : 到这里来问问,看看有什么好的办法用C++来解决。非常感谢!!!!
|
c***s 发帖数: 15 | 33 很简单呀,用模板偏特化,兼顾效率,可读性和可维护性
【在 d**d 的大作中提到】 : 问题是这样的: : 有一段二进制数据,格式是6中格式中的一种。以前我是用C写了6个不同的decoder,每 : 个decoder给主程序提供一个回调函数和一个解码函数。主程序就是把数据的开头的一 : 段送给每个decoder的回调函数来验证一下是不是当前decoder能解码的。如果是的话就 : 调用解码函数来从头处理所有的数据。这个机制目前工作的很好。 : 现在的问题是有一个新的项目也是要处理相同的问题,但是需要的decoder更多,大约 : 需要20几个,大大老板昨天发了一封信说所有的decoder要全部用C++来写。我的思路就 : 被以前的思路给限制住了,感觉没有什么好的办法来解决这个查找decoder的问题。发 : 到这里来问问,看看有什么好的办法用C++来解决。非常感谢!!!!
|
g*****y 发帖数: 7271 | 34 这是lz的要求。有人不是建议加两个byte表明编码方式么。
另外比如图像文件格式的支持,就可以用扩展名来映射。
哪有多少开销。
这种动态决定的事情,reflection貌似用不上的说。
【在 N*****m 的大作中提到】 : 你这个第二步太低效了,30个decoders你一个个试开销太大了
|
c***s 发帖数: 15 | 35 //样本代码如下,把具体decoder方法在不同type上实现就行
#include
enum decoder_type
{
type_A = 0,
type_B = 1,
type_C = 2,
no_decoder_available = 3
};
template
class decoder_algorithm
{
};
template<>
struct decoder_algorithm
{
static bool is_compatible () { return false; }
static void decode() { std::cout << "decoder A" << std::endl; }
};
template<>
struct decoder_algorithm
{
static bool is_compatible () { return false; }
static void decode() { std::cout << "decoder B" << std::endl; }
};
template<>
struct decoder_algorithm
{
static bool is_compatible () { return true; }
static void decode() { std::cout << "decoder C" << std::endl; }
};
template
struct mydecoder
{
static void run()
{
if (decoder_algorithm::is_compatible())
{
decoder_algorithm::decode();
}
else
{
mydecoder::run();
}
}
};
template<>
struct mydecoder
{
static void run()
{
std::cout << "no_decoder_available" << std::endl;
}
};
int main()
{
mydecoder<>::run();
return 0;
} |
d**d 发帖数: 389 | 36 谢谢,这个可行。
我原先准备让factory准备一个static的register函数,然后每个decoder有一个static
的变量。
static boolean decoderXXX::registeStatus=Factory::registerDecoder(std::
function belongToMe, std::function
getInstance)
这样decoder直接就注册了.
【在 c***s 的大作中提到】 : //样本代码如下,把具体decoder方法在不同type上实现就行 : #include : enum decoder_type : { : type_A = 0, : type_B = 1, : type_C = 2, : no_decoder_available = 3 : }; : template
|
c***s 发帖数: 15 | 37 meta programming避开了指针和类型转换,读起来会清晰血多,另外原则上运行效率也
略高一点,那些algorithm的方法都可以inline进去,当然这并不关键。基本上这样的
写法跟直接用if else展开在机器代码上是非常接近的,但是又兼顾了c++的封装原则。
static
【在 d**d 的大作中提到】 : 谢谢,这个可行。 : 我原先准备让factory准备一个static的register函数,然后每个decoder有一个static : 的变量。 : static boolean decoderXXX::registeStatus=Factory::registerDecoder(std:: : function belongToMe, std::function : getInstance) : 这样decoder直接就注册了.
|
y****w 发帖数: 3747 | 38 re. 有时间闲的。
十几年前痴迷c++的那时候有段时间啥东西都generic programming,以写一份code跟
boost对比为乐。后来忽然意识到俺这他妈的自虐啊,干活出活最重要。然后在项目里
严格限制非标准STL的模板使用。
【在 T********i 的大作中提到】 : 别听那些人扯淡。 : 20个decoder算个屁?就用if then else。啥pluggable dll都是扯淡。你又不支持第三 : 方plugin。而且貌似就你一个干活的,连个大team都没有。有必要设计那么复杂的 : contract么? : dll不是光expose api那么简单,还要处理复杂数据结构。尤其是c++。那是dll hell。 : 每次都要编译20多个target,纯粹没事找事。 : 20个if then else,开销是纳秒级别。而且绝对代码最少,出错可能性最小,我打赌不 : 会有任何性能问题。
|
T********i 发帖数: 2416 | 39 不仅仅是干活出活的问题。还有几个更重要的原因。
1。代码清晰易读。
2。省代码。
3。 减少代码耦合度。
20多个parser,小团队,parser数量可能今后几年都没有改变。当然无脑if then else
。而且极有可能能够写出decision tree而不用一个个iteration来判断,速度都是最优
化的。
写一大堆template,读代码的还要去理解,上上下下去来回读。写的麻烦,读也麻烦。
而且可能还要register。一旦忘了可能半天找不到毛病。
多一事不如少一事,别没事找事。
【在 y****w 的大作中提到】 : re. 有时间闲的。 : 十几年前痴迷c++的那时候有段时间啥东西都generic programming,以写一份code跟 : boost对比为乐。后来忽然意识到俺这他妈的自虐啊,干活出活最重要。然后在项目里 : 严格限制非标准STL的模板使用。
|
x****u 发帖数: 44466 | 40 给自己写和给team写,代码要求是不一样的
自己写的话,gp,fp,各种范式哪个省事哪个上,但如果可能被改的面目全非就还是算
了。
else
【在 T********i 的大作中提到】 : 不仅仅是干活出活的问题。还有几个更重要的原因。 : 1。代码清晰易读。 : 2。省代码。 : 3。 减少代码耦合度。 : 20多个parser,小团队,parser数量可能今后几年都没有改变。当然无脑if then else : 。而且极有可能能够写出decision tree而不用一个个iteration来判断,速度都是最优 : 化的。 : 写一大堆template,读代码的还要去理解,上上下下去来回读。写的麻烦,读也麻烦。 : 而且可能还要register。一旦忘了可能半天找不到毛病。 : 多一事不如少一事,别没事找事。
|
|
|
T********i 发帖数: 2416 | 41 写给谁都一样。
就这个需求,20多个decoder,可能几年内都不会增加。有必要写template么?
绝大多数,你没资格,没能力,也没机会写那种成千上万人使用的framework。就是写
给app。简单是王道。
【在 x****u 的大作中提到】 : 给自己写和给team写,代码要求是不一样的 : 自己写的话,gp,fp,各种范式哪个省事哪个上,但如果可能被改的面目全非就还是算 : 了。 : : else
|
x****u 发帖数: 44466 | 42 任何东西只要不在自己手里,其发展都是不可控制的
【在 T********i 的大作中提到】 : 写给谁都一样。 : 就这个需求,20多个decoder,可能几年内都不会增加。有必要写template么? : 绝大多数,你没资格,没能力,也没机会写那种成千上万人使用的framework。就是写 : 给app。简单是王道。
|
c*********e 发帖数: 16335 | 43 二进制数据前端有没有什么能识别它是什么类型数据的?根据这个来选decoder
【在 d**d 的大作中提到】 : 不考虑性能的问题,现在的问题是怎么来设计C++ class来解决这个查找decoder的的问 : 题。 : 基本上是有一个interface class,然后各个decoder来实例这个interface,但是怎么让 : 主程序来查找哪个decoder能用了解码的问题,我就没有头绪了。
|
b*******s 发帖数: 5216 | 44 之前写得很简单,估计没几个人看懂。现在简单解释一下。
这个问题首先是一个运行时问题,因为你无法预测来的数据流是哪一类。我的理解是你得
先decode一段,然后才能检查是不是make sense。
所以模板的编译期特性和魏老师说的一样,帮助不大,组织代码反而可能难懂
其次如果分辨每个流开始的一段如果是非常简单的,比如读几个magic bytes的,那显
然这不是个问题,按照魏老师的办法最简单,顶多再加一个静态频率统计来减少一下分
支预测出错,或者做成switch...case这样的查找表,不需要额外优化
但如果流头部分析很麻烦,比如数据量大或者需要复杂的计算,你二十多个选择过后说
不定比正式处理一个完整的流还费工夫,这时就得采用一些比较聪明的选择
办法不是唯一的,我只是给一个办法,比如头部是 ABBABAAC,而我们有三个解码器,分
别是对应AB ABBAB ABBAC 我们就没必要解析这个头很多遍了,解析完AB后可以继续解
析下去,直到匹配,这个类似trie的做法,最坏就是O(n)
类厂过于笨重,一般只有很大的系统,对象类型极多,使用者花样繁多,这上面的管理
需求非常复杂才用。或者刚开始写程序的半瓶子喜欢用,尤其是改行只学java的。 |
b*******s 发帖数: 5216 | 45 有点像高频系统里面的classifier, 市场信号进来了,是关于一个basket的,但是可能
对应不同策略,得先区分 |
d**d 发帖数: 389 | 46 谢谢各位的输入,我把输入流的情况在说详细一下。
一个几个G的officeline的流或者是streaming进来的流被拿到以后,level 1的decoder
会把流分成不同大小的packet,每个
packet有header和payload。 level 1的decoder需要6个。分包的依据是magic word和
两个固定位置的tag。这个level 1的decoder跟我以前做的相似,就是读一段数据先找
magic word,再找那两个tag,然后根据相对于包的大小开验证是否可以重复magic word
和tags。然后对packet header进行解码。
对于level 1 packet来讲,level 1 decoder在分析包头以后来决定需不需要把不同包
的负载合并成一个新的 level 2 packet,然后调用 level 2 decoder,就是我讲的那20
几个新的decoder. level 2 packet下面实际上还有两个level的信息,结构是一样的,
都是分包头和负载,然后合并成新的包,然后再重复一遍就彻底结束了。我们现在不需
要全部的level 3和level 4信息,只是需要几个,但是将来可能会全部用到。level 3
大约有70个,level 4 大约也有20-30多个。
在level 1 packet的header里面,定义了大约200个不同的descriptor,每个descriptor
有自己的tag来区分。每个level 1 packet的header里面,会有0到N个descriptor,N是
不确定的,每个descriptor出现的概率是相等的。level 1 decoder必须要分析这些
descriptor的。我觉得if/else方法是不可行的。
对于level2,3,4的decoder来讲,查找decoder的原理跟level 1是一样的。level 1
decoder因为数量少,if/else是可行的。但是对于level 2,3,4来讲,我觉得是不行了
。主要问题是 每级的decoder都有可能被上一级的decoder来调用,而不是每一级的
decoder只能调用有限的几个下一级的decoder。特别是对于level 3的decoder来讲,
level 2的decoder要写70多个if/else.这样的话估计 design review的时间就过不了了
。。。。
对于descriptor decoder来讲,因为数量太多,还有可以用tag id来直接确定,我倒是
倾向于用 factory pattern加template function。
factory提供一个template function,用tag来实例化descriptor decoder的对象。
descriptor* factory:: getDescriptorDecoder();
每个descriptorXXX都是基于 descriptor base class的。
对于level 2,3,4 decoder来讲,大家都倾向于不用template,我就还是想回到我的老
的那
一套,decoder class 提供回调函数,供主程序来查询判断然后调用另外的回调函数来
生成新的pointer to decoder object.
非常感谢大家的讨论。
【在 b*******s 的大作中提到】 : 有点像高频系统里面的classifier, 市场信号进来了,是关于一个basket的,但是可能 : 对应不同策略,得先区分
|
b*******s 发帖数: 5216 | 47 Do you mind to give me more colors on this,
"level 1 decoder在分析包头以后来决定需不需要把不同包
的负载合并成一个新的 level 2 packet,然后调用 level 2 decoder"
What is this for? Less call of decoders or to resolve coupling between
packages?
decoder
word
20
【在 d**d 的大作中提到】 : 谢谢各位的输入,我把输入流的情况在说详细一下。 : 一个几个G的officeline的流或者是streaming进来的流被拿到以后,level 1的decoder : 会把流分成不同大小的packet,每个 : packet有header和payload。 level 1的decoder需要6个。分包的依据是magic word和 : 两个固定位置的tag。这个level 1的decoder跟我以前做的相似,就是读一段数据先找 : magic word,再找那两个tag,然后根据相对于包的大小开验证是否可以重复magic word : 和tags。然后对packet header进行解码。 : 对于level 1 packet来讲,level 1 decoder在分析包头以后来决定需不需要把不同包 : 的负载合并成一个新的 level 2 packet,然后调用 level 2 decoder,就是我讲的那20 : 几个新的decoder. level 2 packet下面实际上还有两个level的信息,结构是一样的,
|
d**d 发帖数: 389 | 48 resolve coupling between packages。
level 1 decoder需要读出header里面的descriptor的内容才能知道当前payload是不是
一个有效的paylaod,或者当前payload在level 2 packet里面的位置,比如是不是
level 2 packet的开始数据,或者是最后一段数据,或者是第n/N段数据。有时间level
1 packet的payload就是些无效的填充数据0xFFFF而已。
【在 b*******s 的大作中提到】 : Do you mind to give me more colors on this, : "level 1 decoder在分析包头以后来决定需不需要把不同包 : 的负载合并成一个新的 level 2 packet,然后调用 level 2 decoder" : What is this for? Less call of decoders or to resolve coupling between : packages? : : decoder : word : 20
|