我知道未初始化的局部变量是未定义的行为(UB),并且该值可能具有可能影响进一步操作的陷阱表示,但有时我想仅使用随机数进行可视化表示,并且不会在其他部分使用它们.例如,程序在视觉效果中设置具有随机颜色的东西,例如:
void updateEffect(){
for(int i=0;i<1000;i++){
int r;
int g;
int b;
star[i].setColor(r%255,g%255,b%255);
bool isVisible;
star[i].setVisible(isVisible);
}
}
Run Code Online (Sandbox Code Playgroud)
是不是比它快
void updateEffect(){
for(int i=0;i<1000;i++){
star[i].setColor(rand()%255,rand()%255,rand()%255);
star[i].setVisible(rand()%2==0?true:false);
}
}
Run Code Online (Sandbox Code Playgroud)
并且还比其他随机数发生器更快?
使用lambda表达式是否会为与正常foreach循环相对的GC生成垃圾?
// Lambda version
Foos.ForEach(f=>f.Update(gameTime));
// Normal approach:
foreach (Foo f in Foos)
{
f.Update(gameTime);
}
Run Code Online (Sandbox Code Playgroud)
CLR分析器显示我有69.9%system.Action <T>并且我怀疑是如上所述的foreach循环的lamba版本.真的吗?
编辑:我使用Microsoft CLR分析器:http://download.microsoft.com/download/4/4/2/442d67c7-a1c1-4884-9715-803a7b485b82/clr%20profiler.exe 或http://msdn.microsoft .COM/EN-US /库/ ff650691.aspx
如果函数的返回类型不是void,并且函数没有返回任何内容,那么我猜编译器会返回一个垃圾值(可能被视为未初始化的值).它发生在编译时,为什么不应该抛出错误呢?
例如,
int func1() {
return; // error
}
int func2() {
// does not return anything
}
Run Code Online (Sandbox Code Playgroud)
第二个func2应该抛出错误,但事实并非如此.有原因吗?我的想法是,它可以看作是一个未初始化的值,所以如果我们需要在第二种情况下抛出错误,那么我们需要抛出错误,如果一个值是未初始化的,比如说
int i; // error
int i = 6; // okay
Run Code Online (Sandbox Code Playgroud)
有什么想法,或者这是一个重复的问题?我感谢您的帮助.
我在开发用于异步消息传递的轻量级库的过程中遇到了这种情况。为了了解创建大量寿命较短的中等大小对象的成本,我编写了以下测试:
\nimport java.nio.ByteBuffer;\nimport java.util.Random;\n\n\npublic class MemPressureTest {\n static final int SIZE = 4096;\n static final class Bigish {\n final ByteBuffer b;\n\n\n public Bigish() {\n this(ByteBuffer.allocate(SIZE));\n }\n\n public Bigish(ByteBuffer b) {\n this.b = b;\n }\n\n public void fill(byte bt) {\n b.clear();\n for (int i = 0; i < SIZE; ++i) {\n b.put(bt);\n }\n }\n }\n\n\n public static void main(String[] args) {\n Random random = new Random(1);\n Bigish tmp = new Bigish();\n for (int i = 0; i < 3e7; ++i) …Run Code Online (Sandbox Code Playgroud) 在我的软件中,我有一些使用属性委派的各种值.
这是一个简单的类似示例,显示了我的工作:
class ExampleDelegate<T>(val value: T) {
operator fun getValue(thisRef: Any?, property: KProperty<*>) = value
}
val example by ExampleDelegate(1000) // number larger than 127 (no box cache)
Run Code Online (Sandbox Code Playgroud)
然而,我注意到,引用此值似乎java.lang.Integer在每个引用上创建一个自动装帧的对象().因为该值必须以每秒数百万次或每秒的速度引用,这会导致我的软件产生大量垃圾; 沉重的压力放在垃圾收集器上.
有没有办法避免开销?如果不是直接的,是否有任何聪明的方法来"模仿"高效的财产授权?
提交了有关YouTrack的错误报告:https://youtrack.jetbrains.com/issue/KT-13606
检查时
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char c[20];
size_t l;
l = fread(c, sizeof c, 1, stdin);
if (l != 1)
return 1;
return c[0] == 42;
}
Run Code Online (Sandbox Code Playgroud)
用c,我得到
$ clang --analyze -Xclang -analyzer-checker=alpha x.c
x.c:13:14: warning: The left operand of '==' is a garbage value
return c[0] == 42;
~~~~ ^
$ clang -v
clang version 7.0.1 (Fedora 7.0.1-4.fc29)
Run Code Online (Sandbox Code Playgroud)
此时真的有机会c包含垃圾吗?如果没有,如何避免发出警告(没有对进行明显的初始化c)?
因为这似乎是一个普遍的共识,那就是错误的肯定,所以我想集中讨论如何避免警告。
的确,这fread()是一个标准功能,分析人员应该在执行操作时就memset()已经知道了它们的语义。但是我对更通用的方法感兴趣,例如可以在库函数上使用。
我会assert_defined()以类似的方式调用一些特殊功能(让它调用它)
l = fread(c, …Run Code Online (Sandbox Code Playgroud) 我有一个单一的记录器类.在它的析构函数中,我调用Close()打印日志的页脚,然后关闭StreamWriter.
public void Close()
{
WriteLogFileFooter();
_logFile.Flush();
_logFile.Close();
}
Run Code Online (Sandbox Code Playgroud)
问题是当从程序中的其他地方调用System.Enviornment.Exit(1)时(我自己没有编写的部分),页脚永远不会打印,我的记录器会因尝试写入封闭流而抛出异常.我只能假设Exit命令导致我的StreamWriter在我的Singleton被破坏之前被关闭.我尝试在我的StreamWriter上使用GC.SupressFinalize(),但这似乎没有帮助.
我正在尝试调查带有枚举键的字典是否仍然在较新版本的.Net中产生垃圾(比如说> = 4)
请参阅Shawn Hargreaves博客文章,了解为何我甚至为此烦恼......(http://blogs.msdn.com/b/shawnhar/archive/2007/07/02/twin-paths-to-garbage -collector-nirvana.aspx)非常具体我知道但是xbox上的垃圾是/可能是一个非常棘手的问题.
我创建了一个小的.Net v4控制台应用程序,比较为Dictionary和Dicationary生成的IL,并注意到两组代码中的"盒子"操作码,这让我很困惑.
.method private hidebysig
instance int32 FindEntry (
!TKey key
) cil managed
{
// Method begins at RVA 0x61030
// Code size 138 (0x8a)
.maxstack 3
.locals init (
[0] int32,
[1] int32
)
IL_0000: ldarg.1
IL_0001: box !TKey <----Hmmmm!
IL_0006: brtrue.s IL_000e
IL_0008: ldc.i4.5
IL_0009: call void System.ThrowHelper::ThrowArgumentNullException(valuetype System.ExceptionArgument)
IL_000e: ldarg.0
IL_000f: ldfld int32[] class System.Collections.Generic.Dictionary`2<!TKey, !TValue>::buckets
IL_0014: brfalse.s IL_0088
Run Code Online (Sandbox Code Playgroud)
https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.box%28v=vs.110%29.aspx
将值类型(在valTypeToken中指定的类型)转换为真实对象引用.
这里的盒子不是堆分配吗?如果没有,那么我怎么知道何时存在可能导致Xbox崩溃的堆分配?(从查看IL)它是否依赖于其他一些上下文?内存分析器(例如CLR Profiler)是唯一可以确定的方法吗?
这个问题仅供研究之用.
我读过很多关于C#的书,我总会想到这个问题.据我所知,C#是托管代码,当CLR决定何时运行垃圾收集时,会发生所有垃圾收集.开始吧.
让我们想象一下,我有简单的课程Student:
public class Student
{
public int IdStudent { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
}
class Program
{
static void Main(string[] args)
{
This is row1: Person person = new Person() {IdPerson=1, Name="Bill", SurName="Collins"};
This is row2: System.GC.Collect();
This is row3: string str="Hello World!";
}
}
Run Code Online (Sandbox Code Playgroud)
请批准或拒绝我的假设:
GC.Collect()只是一个要求进行垃圾收集的请求,它不会立即在第2行运行.该行可以以x毫秒/秒执行.在我看来,方法System.GC.Collect();只是向垃圾收集器说垃圾收集器应该运行垃圾收集,但真正的垃圾收集可能发生在x毫秒/秒
只有垃圾收集器才知道何时运行垃圾收集.如果第0代中有可用空间,则 …
garbage ×10
c# ×4
.net ×3
c ×3
c++ ×2
autoboxing ×1
delegates ×1
dictionary ×1
fread ×1
java ×1
jvm ×1
kotlin ×1
linq ×1
performance ×1
pointers ×1
properties ×1
reference ×1
return-value ×1
singleton ×1
xbox360 ×1