avatar
请教一个C++的设计问题# Programming - 葵花宝典
l*6
1
当然了,很大原因是歌写的好,逃跑计划还是蛮有才华的。具体张恒源的唱的吗,只能
说没把好歌糟蹋了
avatar
d*d
2
问题是这样的:
有一段二进制数据,格式是6中格式中的一种。以前我是用C写了6个不同的decoder,每
个decoder给主程序提供一个回调函数和一个解码函数。主程序就是把数据的开头的一
段送给每个decoder的回调函数来验证一下是不是当前decoder能解码的。如果是的话就
调用解码函数来从头处理所有的数据。这个机制目前工作的很好。
现在的问题是有一个新的项目也是要处理相同的问题,但是需要的decoder更多,大约
需要20几个,大大老板昨天发了一封信说所有的decoder要全部用C++来写。我的思路就
被以前的思路给限制住了,感觉没有什么好的办法来解决这个查找decoder的问题。发
到这里来问问,看看有什么好的办法用C++来解决。非常感谢!!!!
avatar
n*j
3
不管用什么写,都得把数据开头送给 decoder,除非数据包头有 magic code 能节省一
点时间,否则 c++ 和 c 没区别。

【在 d**d 的大作中提到】
: 问题是这样的:
: 有一段二进制数据,格式是6中格式中的一种。以前我是用C写了6个不同的decoder,每
: 个decoder给主程序提供一个回调函数和一个解码函数。主程序就是把数据的开头的一
: 段送给每个decoder的回调函数来验证一下是不是当前decoder能解码的。如果是的话就
: 调用解码函数来从头处理所有的数据。这个机制目前工作的很好。
: 现在的问题是有一个新的项目也是要处理相同的问题,但是需要的decoder更多,大约
: 需要20几个,大大老板昨天发了一封信说所有的decoder要全部用C++来写。我的思路就
: 被以前的思路给限制住了,感觉没有什么好的办法来解决这个查找decoder的问题。发
: 到这里来问问,看看有什么好的办法用C++来解决。非常感谢!!!!

avatar
d*d
4
不考虑性能的问题,现在的问题是怎么来设计C++ class来解决这个查找decoder的的问
题。
基本上是有一个interface class,然后各个decoder来实例这个interface,但是怎么让
主程序来查找哪个decoder能用了解码的问题,我就没有头绪了。

【在 n****j 的大作中提到】
: 不管用什么写,都得把数据开头送给 decoder,除非数据包头有 magic code 能节省一
: 点时间,否则 c++ 和 c 没区别。

avatar
d*n
5
把decoder试错的顺序按照数据的频率从高到低排序就可以了。水平高的再搞个动态的
排序。
写程序逻辑越简单越好。

【在 d**d 的大作中提到】
: 问题是这样的:
: 有一段二进制数据,格式是6中格式中的一种。以前我是用C写了6个不同的decoder,每
: 个decoder给主程序提供一个回调函数和一个解码函数。主程序就是把数据的开头的一
: 段送给每个decoder的回调函数来验证一下是不是当前decoder能解码的。如果是的话就
: 调用解码函数来从头处理所有的数据。这个机制目前工作的很好。
: 现在的问题是有一个新的项目也是要处理相同的问题,但是需要的decoder更多,大约
: 需要20几个,大大老板昨天发了一封信说所有的decoder要全部用C++来写。我的思路就
: 被以前的思路给限制住了,感觉没有什么好的办法来解决这个查找decoder的问题。发
: 到这里来问问,看看有什么好的办法用C++来解决。非常感谢!!!!

avatar
d*d
6
写20几个if/else? 不会吧?

【在 d****n 的大作中提到】
: 把decoder试错的顺序按照数据的频率从高到低排序就可以了。水平高的再搞个动态的
: 排序。
: 写程序逻辑越简单越好。

avatar
g*y
7
每个decoder register一下,然后loop就好。扩展decoder就很容易了。

【在 d**d 的大作中提到】
: 写20几个if/else? 不会吧?
avatar
d*d
8
这个就是我一开用C的写法,每个decoder去主程序register一下回调函数和解码函数。
对于C++,我原先想的是如果每个decoder的class都定义一个static的格式判断函数和
static decoder* geInstance(),然后都在主程序登记一下。主程序还是用loop来调用
每一个decoder的格式判断函数,如果是正确的格式,再调用getInstance(),然后调用
解码函数。这样的话用C++类的写法也没有太多的优势。
还是有更好的设计方法和思路?

【在 g*****y 的大作中提到】
: 每个decoder register一下,然后loop就好。扩展decoder就很容易了。
avatar
k*g
9
可以用hash对数据头生成一个数,然后直接调用对应的decoder,省去20几次判断了
C++面向对象的特性感觉这种场景用不上

【在 d**d 的大作中提到】
: 问题是这样的:
: 有一段二进制数据,格式是6中格式中的一种。以前我是用C写了6个不同的decoder,每
: 个decoder给主程序提供一个回调函数和一个解码函数。主程序就是把数据的开头的一
: 段送给每个decoder的回调函数来验证一下是不是当前decoder能解码的。如果是的话就
: 调用解码函数来从头处理所有的数据。这个机制目前工作的很好。
: 现在的问题是有一个新的项目也是要处理相同的问题,但是需要的decoder更多,大约
: 需要20几个,大大老板昨天发了一封信说所有的decoder要全部用C++来写。我的思路就
: 被以前的思路给限制住了,感觉没有什么好的办法来解决这个查找decoder的问题。发
: 到这里来问问,看看有什么好的办法用C++来解决。非常感谢!!!!

avatar
b*s
10
trie, only if headers are really heavy burden to analysis
avatar
b*s
11
or a chain of functions for detecting, so you only have to parse the header
once
avatar
b*s
12
the essence of this thing is a kind of parser
avatar
w*g
13
我有个项目跟你这个有点像。接受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++来解决。非常感谢!!!!

avatar
y*r
14
这就是一简单的factory pattern。
avatar
w*g
15
标准实现是啥?

【在 y*****r 的大作中提到】
: 这就是一简单的factory pattern。
avatar
d*d
16
对,就是这样的问题。我不想去扫描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程序自己)。这种做法可以把所有的东西全都编译成一个可执行文件。

avatar
d*d
17
我觉得要是用factory pattern来做的话,factory需要去分析header,然后从分析结果
里面来决定产生哪个decoder。这样的话实际上是把decoder的分析工作放到了factory
里面。将来如果还要加新的decoder的话,还要去改factory那方面的代码,不好维护。
不知道是不是你有更好的想法?

【在 y*****r 的大作中提到】
: 这就是一简单的factory pattern。
avatar
p*g
18
扫描目录有什么难得。直接用boost。 你 dlopen 一个和多个 so 有什么区别?
或者你写一个配置文件里面列出来所有的decoder function 的名字, 所在的so文件。
程序加载的时候就毒一下这个文件dlopen 然后找到所有的decoder集中放一起就完了。
这个问题和c艹 真的没啥关系。c/c艹 没什么大区别

decoder

【在 d**d 的大作中提到】
: 对,就是这样的问题。我不想去扫描plugin目录,太麻烦。就是直接把所有的decoder
: 放进一个so文件里面。

avatar
p*g
19
你的各个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++类的写法也没有太多的优势。
: 还是有更好的设计方法和思路?

avatar
y*r
20
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那方面的代码,不好维护。
: 不知道是不是你有更好的想法?

avatar
N*m
21
Java做很简单
c++没有reflection,所以得自己手动搞

factory

【在 d**d 的大作中提到】
: 我觉得要是用factory pattern来做的话,factory需要去分析header,然后从分析结果
: 里面来决定产生哪个decoder。这样的话实际上是把decoder的分析工作放到了factory
: 里面。将来如果还要加新的decoder的话,还要去改factory那方面的代码,不好维护。
: 不知道是不是你有更好的想法?

avatar
g*y
22
你可以看一下那个所谓的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++类的写法也没有太多的优势。
: 还是有更好的设计方法和思路?

avatar
g*y
23
自动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程序自己)。这种做法可以把所有的东西全都编译成一个可执行文件。

avatar
g*y
24
这和reflection没什么关系吧?
很多tricks其实就是share factory code或者自动registering之类的。
大多数都是利用template来搞。不知道Java的template好用不,
从来没有试过。

【在 N*****m 的大作中提到】
: Java做很简单
: c++没有reflection,所以得自己手动搞
:
: factory

avatar
g*y
25
是factory pattern。分析部分通过调用每个decoder提供的callback就好。
factory的code相对很稳定,不用怎么改。就是所谓的pluggable factory了。

factory

【在 d**d 的大作中提到】
: 我觉得要是用factory pattern来做的话,factory需要去分析header,然后从分析结果
: 里面来决定产生哪个decoder。这样的话实际上是把decoder的分析工作放到了factory
: 里面。将来如果还要加新的decoder的话,还要去改factory那方面的代码,不好维护。
: 不知道是不是你有更好的想法?

avatar
N*m
26
楼上说的是不想把header->decoder hardcoded
如果有reflection,直接用个property file定义,runtime load就好了

【在 g*****y 的大作中提到】
: 这和reflection没什么关系吧?
: 很多tricks其实就是share factory code或者自动registering之类的。
: 大多数都是利用template来搞。不知道Java的template好用不,
: 从来没有试过。

avatar
g*y
27
这就是register新的decoder的部分吧?C/C++也不用改code啊,
如果是dll的话,只要把新的decoder的dll放到指定目录,
就可以自动load了。
如果静态连接,新decoder的文件里需要register它自己。
不用改别的文件。有很多通过继承来完成自动register的
做法。reflection在这上面没什么优势吧。

【在 N*****m 的大作中提到】
: 楼上说的是不想把header->decoder hardcoded
: 如果有reflection,直接用个property file定义,runtime load就好了

avatar
N*m
28
load decoders不是问题
问题是怎么不用重新编译,把header跟decoder对应起来

【在 g*****y 的大作中提到】
: 这就是register新的decoder的部分吧?C/C++也不用改code啊,
: 如果是dll的话,只要把新的decoder的dll放到指定目录,
: 就可以自动load了。
: 如果静态连接,新decoder的文件里需要register它自己。
: 不用改别的文件。有很多通过继承来完成自动register的
: 做法。reflection在这上面没什么优势吧。

avatar
g*y
29
照我理解,以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对应起来

avatar
N*m
30
你这个第二步太低效了,30个decoders你一个个试开销太大了

【在 g*****y 的大作中提到】
: 照我理解,以dll办法为例:
: 1. 所有找到的某个目录下的decoder dlls,加入链表;
: 2. 把header依次传给decoder的回调函数来分析header并返回是否接受;
: 3. 如果某一个decoder回调函数返回接受,就把数据传给该decoder的
: decode回调函数;
: 分析header的回调函数是decoder来implement的。新decoder
: 的code当然需要编译成dll。除了这个,还有什么要重新编译的么?
: 哪个语言里新的decoder都要重新编译吧?

avatar
r*g
31
看了一下问题本身
感觉这个东西并不是哪里不可完成
难度主要在体力上吧?
或者我简单化了某些问题
总之我觉得越简单越好

【在 d**d 的大作中提到】
: 问题是这样的:
: 有一段二进制数据,格式是6中格式中的一种。以前我是用C写了6个不同的decoder,每
: 个decoder给主程序提供一个回调函数和一个解码函数。主程序就是把数据的开头的一
: 段送给每个decoder的回调函数来验证一下是不是当前decoder能解码的。如果是的话就
: 调用解码函数来从头处理所有的数据。这个机制目前工作的很好。
: 现在的问题是有一个新的项目也是要处理相同的问题,但是需要的decoder更多,大约
: 需要20几个,大大老板昨天发了一封信说所有的decoder要全部用C++来写。我的思路就
: 被以前的思路给限制住了,感觉没有什么好的办法来解决这个查找decoder的问题。发
: 到这里来问问,看看有什么好的办法用C++来解决。非常感谢!!!!

avatar
x*u
32
如果用dll自然是直接做成com组件了,所有的坑ms都帮你踩过几百遍了。

【在 g*****y 的大作中提到】
: 照我理解,以dll办法为例:
: 1. 所有找到的某个目录下的decoder dlls,加入链表;
: 2. 把header依次传给decoder的回调函数来分析header并返回是否接受;
: 3. 如果某一个decoder回调函数返回接受,就把数据传给该decoder的
: decode回调函数;
: 分析header的回调函数是decoder来implement的。新decoder
: 的code当然需要编译成dll。除了这个,还有什么要重新编译的么?
: 哪个语言里新的decoder都要重新编译吧?

avatar
T*i
33
别听那些人扯淡。
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++来解决。非常感谢!!!!

avatar
c*s
34
很简单呀,用模板偏特化,兼顾效率,可读性和可维护性

【在 d**d 的大作中提到】
: 问题是这样的:
: 有一段二进制数据,格式是6中格式中的一种。以前我是用C写了6个不同的decoder,每
: 个decoder给主程序提供一个回调函数和一个解码函数。主程序就是把数据的开头的一
: 段送给每个decoder的回调函数来验证一下是不是当前decoder能解码的。如果是的话就
: 调用解码函数来从头处理所有的数据。这个机制目前工作的很好。
: 现在的问题是有一个新的项目也是要处理相同的问题,但是需要的decoder更多,大约
: 需要20几个,大大老板昨天发了一封信说所有的decoder要全部用C++来写。我的思路就
: 被以前的思路给限制住了,感觉没有什么好的办法来解决这个查找decoder的问题。发
: 到这里来问问,看看有什么好的办法用C++来解决。非常感谢!!!!

avatar
g*y
35
这是lz的要求。有人不是建议加两个byte表明编码方式么。
另外比如图像文件格式的支持,就可以用扩展名来映射。
哪有多少开销。
这种动态决定的事情,reflection貌似用不上的说。

【在 N*****m 的大作中提到】
: 你这个第二步太低效了,30个decoders你一个个试开销太大了
avatar
c*s
36
//样本代码如下,把具体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;
}
avatar
d*d
37
谢谢,这个可行。
我原先准备让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

avatar
c*s
38
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直接就注册了.

avatar
y*w
39
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,开销是纳秒级别。而且绝对代码最少,出错可能性最小,我打赌不
: 会有任何性能问题。

avatar
T*i
40
不仅仅是干活出活的问题。还有几个更重要的原因。
1。代码清晰易读。
2。省代码。
3。 减少代码耦合度。
20多个parser,小团队,parser数量可能今后几年都没有改变。当然无脑if then else
。而且极有可能能够写出decision tree而不用一个个iteration来判断,速度都是最优
化的。
写一大堆template,读代码的还要去理解,上上下下去来回读。写的麻烦,读也麻烦。
而且可能还要register。一旦忘了可能半天找不到毛病。
多一事不如少一事,别没事找事。

【在 y****w 的大作中提到】
: re. 有时间闲的。
: 十几年前痴迷c++的那时候有段时间啥东西都generic programming,以写一份code跟
: boost对比为乐。后来忽然意识到俺这他妈的自虐啊,干活出活最重要。然后在项目里
: 严格限制非标准STL的模板使用。

avatar
x*u
41
给自己写和给team写,代码要求是不一样的
自己写的话,gp,fp,各种范式哪个省事哪个上,但如果可能被改的面目全非就还是算
了。

else

【在 T********i 的大作中提到】
: 不仅仅是干活出活的问题。还有几个更重要的原因。
: 1。代码清晰易读。
: 2。省代码。
: 3。 减少代码耦合度。
: 20多个parser,小团队,parser数量可能今后几年都没有改变。当然无脑if then else
: 。而且极有可能能够写出decision tree而不用一个个iteration来判断,速度都是最优
: 化的。
: 写一大堆template,读代码的还要去理解,上上下下去来回读。写的麻烦,读也麻烦。
: 而且可能还要register。一旦忘了可能半天找不到毛病。
: 多一事不如少一事,别没事找事。

avatar
T*i
42
写给谁都一样。
就这个需求,20多个decoder,可能几年内都不会增加。有必要写template么?
绝大多数,你没资格,没能力,也没机会写那种成千上万人使用的framework。就是写
给app。简单是王道。

【在 x****u 的大作中提到】
: 给自己写和给team写,代码要求是不一样的
: 自己写的话,gp,fp,各种范式哪个省事哪个上,但如果可能被改的面目全非就还是算
: 了。
:
: else

avatar
x*u
43
任何东西只要不在自己手里,其发展都是不可控制的

【在 T********i 的大作中提到】
: 写给谁都一样。
: 就这个需求,20多个decoder,可能几年内都不会增加。有必要写template么?
: 绝大多数,你没资格,没能力,也没机会写那种成千上万人使用的framework。就是写
: 给app。简单是王道。

avatar
c*e
44
二进制数据前端有没有什么能识别它是什么类型数据的?根据这个来选decoder

【在 d**d 的大作中提到】
: 不考虑性能的问题,现在的问题是怎么来设计C++ class来解决这个查找decoder的的问
: 题。
: 基本上是有一个interface class,然后各个decoder来实例这个interface,但是怎么让
: 主程序来查找哪个decoder能用了解码的问题,我就没有头绪了。

avatar
b*s
45
之前写得很简单,估计没几个人看懂。现在简单解释一下。
这个问题首先是一个运行时问题,因为你无法预测来的数据流是哪一类。我的理解是你得
先decode一段,然后才能检查是不是make sense。
所以模板的编译期特性和魏老师说的一样,帮助不大,组织代码反而可能难懂
其次如果分辨每个流开始的一段如果是非常简单的,比如读几个magic bytes的,那显
然这不是个问题,按照魏老师的办法最简单,顶多再加一个静态频率统计来减少一下分
支预测出错,或者做成switch...case这样的查找表,不需要额外优化
但如果流头部分析很麻烦,比如数据量大或者需要复杂的计算,你二十多个选择过后说
不定比正式处理一个完整的流还费工夫,这时就得采用一些比较聪明的选择
办法不是唯一的,我只是给一个办法,比如头部是 ABBABAAC,而我们有三个解码器,分
别是对应AB ABBAB ABBAC 我们就没必要解析这个头很多遍了,解析完AB后可以继续解
析下去,直到匹配,这个类似trie的做法,最坏就是O(n)
类厂过于笨重,一般只有很大的系统,对象类型极多,使用者花样繁多,这上面的管理
需求非常复杂才用。或者刚开始写程序的半瓶子喜欢用,尤其是改行只学java的。
avatar
b*s
46
有点像高频系统里面的classifier, 市场信号进来了,是关于一个basket的,但是可能
对应不同策略,得先区分
avatar
d*d
47
谢谢各位的输入,我把输入流的情况在说详细一下。
一个几个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的,但是可能
: 对应不同策略,得先区分

avatar
b*s
48
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的信息,结构是一样的,

avatar
d*d
49
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

相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。