假设我正在实现一个字节码编译器,类似于Lua的/ Python ......等等.
我正在遍历AST,生成字节码指令,并且我遇到了循环break内部的if-else内部while:
while (cond1)
if (cond2)
...
else
break
Run Code Online (Sandbox Code Playgroud)
(我尝试写出等效的字节码,但它看起来并没有太大帮助.)
关键是,该示例中至少有4个"跳转"指令,我想找到一个优雅的解决方案来填充跳转地址,因为我编译AST ...我不知道while循环的跳转地址或者break直到我完全"编译"内部陈述之后.
我还没读这本龙书.
如果我递归地编译AST,当我break在一些任意数量的循环和if-else块中找到一个语句时,编译器应该如何知道跳转到哪个空标签?我猜测递归AST行走函数外部的某种类型的标签名称堆栈.
我有一个生产者 - 消费者场景,生产者生产的速度比消费者消费的快得多.通常,解决方案是使生产者阻止,因为生产者/消费者场景的运行速度与最慢的组件一样快.限制或阻止生产者并不是一个好的解决方案,因为我们的应用程序为消费者提供了足够的时间来赶上.
这是一个图表,描绘了我们的应用程序中的完整"阶段"与更常见的场景:
Our Application Common Scenario
2N +--------+--------+
|PPPPPPPP|oooooooo| P = Producer
|PPPPPPPP|oooooooo| C = Consumer
N +--------+--------+ N +--------+--------+--------+ o = Other Work
|CPCPCPCP|CCCCCCCC| |CPCPCPCP|CPCPCPCP|oooooooo| N = number of tasks
|CPCPCPCP|CCCCCCCC| |CPCPCPCP|CPCPCPCP|oooooooo|
------------------- ----------------------------
0 T/2 T 0 T/2 T 3T/2
Run Code Online (Sandbox Code Playgroud)
我们的想法是通过不抑制生产者来最大化吞吐量.
我们的任务运行的数据很容易被序列化,因此我计划实现一个文件系统解决方案,以便溢出所有无法立即满足的任务.
我正在使用具有最大容量的Java ThreadPoolExecutor,BlockingQueue以确保我们不会耗尽内存.问题是在实施这样的"分层"的队列,在那里是可以在内存中排队的任务是如此立即执行,否则数据被排队在磁盘上.
我想出了两个可能的解决方案:
BlockingQueue从无到有,使用LinkedBlockingQueue或ArrayBlockingQueue实施作为参考.这可能就像在标准库中复制实现并添加文件系统读/写一样简单.BlockingQueue实施,实现一个独立的FilesystemQueue存储我的数据,并使用一个或多个线程出列文件,创建RunnableS和使用他们排队ThreadPoolExecutor.这些都是合理的,是否有更好的方法?
我正在将文件转换代码从专有文件格式写入一个更通用的.我的目标是支持制造商文件格式的多个版本.
我有相同专有标头的多个版本.标题定义了构成主文件头的各种结构(文件只是一个大标题,后跟原始数据).
我需要读取源文件的前4个字节来确定文件版本.反过来,文件版本告诉我使用哪个版本的C-structs来创建文件.
问题是:
可能的解决方案:
我尝试过使用命名空间进行黑客攻击:
namespace version1 {
#include "version1.h"
}
namespace version2 {
#include "version2.h"
}
int main (void) {
version1::header *hdr = new version1::header;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但这不会起作用,因为包括警卫,并且因为在每个标题中重新定义了多个宏.
有一种优雅的方式来处理这个问题吗?
我的目标是编写一个简单的泛型函数,用于注册任意C ++类型的转换器。为了简单起见,我只打印C ++类型名称。我希望能够print_type_name针对任何类型调用我的泛型函数,包括一次调用多个类型(可变):
template <typename T>
void print_type_name(void)
{
std::cout << typeid(T).name() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
对于以下情况,这可以正常工作:
print_type_name<int>();
print_type_name<std::string>();
print_type_name<std::vector<std::complex<float> > >();
Run Code Online (Sandbox Code Playgroud)
但是,我需要能够为可变参数模板中的每种类型调用此函数,例如(展开时):
print_type_name<int, std::string, std::vector<std::complex<float> > >();
Run Code Online (Sandbox Code Playgroud)
这是我想出的,但是很笨拙:
template <typename ...TS>
void noop(TS... ts) { }
template <typename T>
int real_print_type_name(void) {
std::cout << typeid(T).name() << std::endl;
return 0;
}
template <typename ...TS>
void print_type_name(void) {
noop(real_print_type_name<TS>()...);
}
Run Code Online (Sandbox Code Playgroud)
其中包括以下内容:
template <typename ...TS>
void other_function(void) {
print_type_name<TS...>();
}
Run Code Online (Sandbox Code Playgroud)
请注意无用的noop函数和的int返回类型
real_print_type_name,为了扩展参数包,我必须添加这两个函数。有没有更干净的方法可以做到这一点?