首先,通过SBT进行的增量构建非常棒,通常在<1秒范围内.但是,有时您必须进行完全清理/编译,或者在增量构建的情况下,您对一个文件进行更改,然后触发编译其他几十个文件.
这就是Scala开发变得不那么有趣了,因为工作流程的减慢可以鼓励上下文切换(检查电子邮件,最新的Stackoverflow线程等),这会巧妙地降低工作效率
那么,为了改进完整的清理/编译构建,以及(理想情况下)更改一个文件而不重新编译一半应用程序增量构建,需要避免哪些开发方法?
我可以想到的例子:
1)最好有一千个+行全部scala文件,或者几个文件分开?
2)我可以拥有蛋糕(模式)还是会延长构建时间?
3)我可以拥有pimp'd x,y,z库模式,还是更好地找到另一种方式?
4)包装对象(带有隐含)是构建时间杀手吗?
5)嵌套对象和特征?
6)隐含的方法/参数或停止聪明和明确?
具体来说,我正在考虑放弃一个蛋糕模式DAO我提出并整合到ScalaQuery案例类+伴随对象+最小数据库提供程序特征.仅此一项就可以删除20个scala文件.
应用程序足够小(120 scala + 10个java文件)现在重构,没有太多麻烦.显然,随着scala应用程序的增长,构建时间也会增长,仅基于LOC.我只是想看看在哪里修剪脂肪以及在哪里不打扰(即保持原样),因此当前和未来的应用程序将受益于scala提供的表现力,而不会不必要地增加构建时间.
感谢您在构建时间内体验scala开发的好,坏和丑的一些示例.
基本上我想在我的代码中能够做到这一点:
Engine.getById(WSID('some-id'));
Run Code Online (Sandbox Code Playgroud)
哪个应该改变
Engine.getById('1a61bc96');
Run Code Online (Sandbox Code Playgroud)
就在编译成asm之前.所以在编译时.
这是我的尝试
constexpr int WSID(const char* str) {
boost::crc_32_type result;
result.process_bytes(str,sizeof(str));
return result.checksum();
}
Run Code Online (Sandbox Code Playgroud)
但是在尝试使用MSVC 18(CTP 2013年11月)编译时我得到了这个
error C3249: illegal statement or sub-expression for 'constexpr' function
Run Code Online (Sandbox Code Playgroud)
WSID只要在编译期间完成,我怎样才能以这种方式或任何方式获得该函数?
试过这个:编译时间字符串哈希
warning C4592: 'crc32': 'constexpr' call evaluation failed; function will be called at run-time
Run Code Online (Sandbox Code Playgroud)
编辑:
我第一次在Jason Gregory的游戏引擎架构中听说过这种技术.我联系了那位有意回答我的作者:
我们所做的是通过一个自定义的小预处理器传递我们的源代码,该预处理器搜索表单的文本
SID('xxxxxx')并将单引号之间的任何内容转换为其哈希等效项作为十六进制文字(0xNNNNNNNN).[...]你可以想象通过宏和/或一些模板元编程也可以做到这一点,尽管如你所说让编译器为你做这种工作是很棘手的.这并非不可能,但编写自定义工具更容易,也更灵活.[...]
另请注意,我们为
SID('xxxx')文字选择单引号.这样做是为了让我们在代码编辑器中得到一些合理的语法突出显示,但是如果出现问题并且一些未预处理的代码通过编译器,它会引发语法错误,因为单引号通常是保留的单字符文字.另请注意,让您的小预处理工具将字符串缓存到某种类型的数据库中是至关重要的,这样可以在给定哈希码的情况下查找原始字符串.当您调试代码并检查
StringId变量时,调试器通常会向您显示相当难以理解的哈希代码.但是使用SID数据库,您可以编写一个插件,将这些哈希代码转换回其字符串等效项.这样,你会在你的观察窗口看到SID('foo'),而不是0x75AE3080[...].此外,游戏应该能够加载这个相同的数据库,以便它可以在屏幕上打印字符串而不是十六进制哈希码用于调试目的[...].
但是虽然预处理有一些主要优点,但这意味着我必须准备一些修改文件的输出系统(那些将存储在别处,然后我们需要告诉MSVC).因此,它可能会使编译任务复杂化.有没有办法用python预处理文件,例如没有头痛?但这不是问题,我仍然对使用编译时功能感兴趣(关于缓存我可以使用ID索引)
在Objective-C中,当您声明一个实例变量时,您可以检查它是否符合编译时分配的协议,如下所示:
id <MyProtocol> variable;
Run Code Online (Sandbox Code Playgroud)
是否有可能在编译时检查分配给变量的对象是否符合两个单独的协议?如:
id <MyProtocol, MyOtherProtocol> variable;
Run Code Online (Sandbox Code Playgroud)
我知道我可以使用conformsToProtocol:and respondsToSelectoral等进行运行时检查(我在实际使用对象之前做的是为了增加安全性),我可以编写自己的setter方法进行检查,但我想在编译时知道.
我在Haskell中有一个持续的声明 - 我可以提前对它进行评估吗?我看到一些看起来很像的代码,
myList = [(a, b), (c, d)]
...
map (f . fst) myList
Run Code Online (Sandbox Code Playgroud)
fst当我对它进行分析时,它会在通话中占用一些时间(它有168M的呼叫).二进制表示myList非常小,例如,可以复制到全局内存[如果这是一个C程序].我正在编译-O3 -optc-O3.
非常感谢!
lift在sclv的答案中给出调用的任何表达式都必须是Lift的一个实例.有一个名为library的库th-lift,它将为自定义数据类型生成Lift实例.查看该软件包的文档.
performance haskell lazy-evaluation compile-time template-haskell
我已就此主题提出了很多问题,但到目前为止找不到任何解决方案.这里提到了一个自然的解决方案:在编译时确定字节序.
但是,评论中提到的相关问题和答案相同.
通过一些修改,我能够在-std=c++11没有任何警告的情况下使用g ++和clang ++()编译类似的解决方案.
static_assert(sizeof(char) == 1, "sizeof(char) != 1");
union U1
{
int i;
char c[sizeof(int)];
};
union U2
{
char c[sizeof(int)];
int i;
};
constexpr U1 u1 = {1};
constexpr U2 u2 = {{1}};
constexpr bool IsLittleEndian ()
{
return u1.i == u2.c[0]; // ignore different type comparison
}
static_assert(IsLittleEndian(), "The machine is BIG endian");
Run Code Online (Sandbox Code Playgroud)
演示.
这可以被认为是决定字节序的确定性方法还是错过类型惩罚或其他什么?
如果我写
enum chars = digits ~ uppercase;
Run Code Online (Sandbox Code Playgroud)
字符串是否会在编译时连接?我假设它会.如果我用字符串文字或CTFE函数替换它,我无法测量任何显着的性能差异(甚至称它为一亿次).如果我用const替换enum,我确实会有所不同.我被告知这样编写效率很低.我觉得这很方便,我看不出效率低下.(顺便说一句,该行是一个递归调用的函数).
完整代码(转换为具有不同基数的数字系统)
import std.string;
string toBase(long n, int b)
in {
assert(2 <= b && b <= 35);
} body {
static string sign;
if (n < 0) {
n *= -1;
sign = "-";
}
enum chars = digits ~ uppercase;
size_t r = cast(size_t)(n % b);
if (n == r) {
return sign ~ chars[r];
}
return toBase((n - r) / b, b) ~ chars[r];
}
Run Code Online (Sandbox Code Playgroud)
编辑:更新的代码,以回应评论,与问题无关
string toBase(long n, int …Run Code Online (Sandbox Code Playgroud) 从C++来了,我曾经是能够建立编译时断言,在那里我可以在编译时发出警告或错误的简单形式,如果一些简单的条件(例如在简单的代数表达式)未通过使用模板元的满足 - 编程和/或 cpp(1)
举例来说,如果我想确保我的程序时,只编译Int至少有一定的minBound/ maxBound范围或替代,如果从(如可逆)无损耗转换Int64到Int可能与当前编译目标.这可能是GHC Haskell扩展的一部分吗?我的第一个猜测是使用TH.是否有其他GHC设施可以被利用?
我想为Data.Map创建一个特殊的智能构造函数,对键/值对关系的类型有一定的约束.这是我试图表达的约束:
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, DataKinds #-}
data Field = Speed | Name | ID
data Value = VFloat Float | VString ByteString | VInt Int
class Pair f b | f -> b where
toPair :: f -> b -> (f, b)
toPair = (,)
instance Pair Speed (VFloat f)
instance Pair ID (VInt i)
Run Code Online (Sandbox Code Playgroud)
对于每个字段,只应该与其关联的一种类型的值.就我而言,一个Speed字段映射到一个字段是没有意义的ByteString.一个Speed字段应该唯一映射到一个Float
但是我收到以下类型错误:
Kind mis-match
The first argument of `Pair' should have kind `*',
but `VInt' has kind …Run Code Online (Sandbox Code Playgroud) haskell compile-time type-constraints functional-dependencies gadt
我正在尝试定义一个结构,该结构使用具有有限数字范围的变量,以及来自整数的隐式强制.如果任何常量或其他硬编码值与此结构一起使用,我希望能够强制构建错误.
这是我想要完成的一个例子.
byte a = 123; // Allowed
byte b = 123123; // Not allowed
const int x = 123;
const int y = 123123;
byte c = x; // Allowed
byte d = y; // Not allowed
Run Code Online (Sandbox Code Playgroud)
理想情况下,我希望能够将数字限制在1到99之间,以便MyStruct s = 50; 但是MyStruct s = 150; 导致编译时错误,如上面的字节b和d.
我发现了一种类似于不同语言的东西,但不是C#.
我有与Dave Durbin相同的先决条件如何在C中实现动态调度表 ...除了我的目标是AVR.这是我的约束:
通常,该表应包含此类型的项目:
typedef struct jump_item {
uint16_t function_id;
void (*callback)(void);
} jump_item_t;
Run Code Online (Sandbox Code Playgroud)
我已经尝试使用答案中建议的自定义部分,但是链接器会为未知符号抛出错误__start_myownsection(无论我使用哪个部分名称).当然,因为代码的目标是Linux/GCC.但我认为我很接近,因为avr-gcc实际上可以使用部分,只是因为我还没有弄清楚如何在用户定义的部分中堆叠符号并实际指向表的开头,以及确定表的长度在运行时.
怎么能艺术的回答适应AVR?
*编辑*
我可以看到至少两种方法来实现我想要的部分,或者使用"附加"到用户定义部分的函数或者结构表(如上所定义),这些部分将在用户定义的部分中堆叠.我目前的问题是:
-gc-sections,链接时未使用的函数被优化掉,我需要清理未使用的函数.我更喜欢第二个选项,类似于:
module1.c:
const jump_item_t module1_table[] __attribute__((__progmem__, section("tbl_dispatch"))) =
{
{ 0x02, func11 },
{ 0x03, func12 },
...
};
Run Code Online (Sandbox Code Playgroud)
module2.c:
const jump_item_t module2_table[] __attribute__((__progmem__, section("tbl_dispatch"))) =
{
{ 0x12, func21 },
{ 0x13, func22 },
...
};
Run Code Online (Sandbox Code Playgroud)
注意:指数不应被视为相关.
当所有模块都定义了这些变量时,它们会被优化掉,因为没有任何参考这些变量.他们需要在部分中叠加tbl_dispatch.所以我的问题可以追溯到:
如何告诉编译器删除它"认为"未被使用但仅使用特定C/C++模块的变量? …
compile-time ×10
haskell ×3
c++ ×2
c++11 ×2
performance ×2
avr-gcc ×1
c# ×1
cocoa ×1
cocoa-touch ×1
coercion ×1
constexpr ×1
d ×1
endianness ×1
gadt ×1
ghc ×1
objective-c ×1
protocols ×1
scala ×1
type-punning ×1