今天我测试了与Node.js相比,在c#命令行应用程序中需要多少内存。 这是我在Node.js中的代码:
"use strict";
class User{
constructor(firstname, lastname){
this.firstName = firstname;
this.lastName = lastname;
}
}
const count = 10000000;
const users = [];
console.time('Allocating Elements');
for (let i = 0; i < count; i++) {
users.push(new User(`John${i}`,`Doe${i}`));
}
console.timeEnd('Allocating Elements');
console.log('Finished');
这是我在C#中的代码:
class User
{
public string firstName { get; set; }
public string lastName { get; set; }
public User(string firstname, string lastname)
{
this.firstName = firstName;
this.lastName = lastName;
}
}
class Program
{
static void Main(string[] args)
{
var count = 10000000;
var users = new List<User>();
var sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
{
users.Add(new User($"John{i}", $"Doe{i}"));
}
sw.Stop();
Console.WriteLine($"Allocating Elements: {sw.ElapsedMilliseconds}");
Console.WriteLine("Finished");
}
}
两个程序都以64位执行。
当我在c#中使用类型对象列表时,ram消耗大致相同。
所以我的问题是:如果我在c#中使用User类,为什么Node需要大约4倍的ram?这样的优化怎么可能?
我附上了两个进程的ram用法的截图,当它们最后站在一个断点时。
答案 0 :(得分:1)
我无法对C#发表评论,但我可以告诉你V8为你的例子消耗了多少内存。对于每个User
对象,它都需要:
&#34;用户&#34;对象本身:
firstNameString,lastNameString:
(字符串对象向上舍入到指针大小对齐。前10,000和#34; John&#34;字符串和前100,000&#34; Doe&#34;字符串每个只包含四个单词,但与总共有20,000,000个字符串,这个影响可以忽略不计。)
最后:
users
数组当你全部添加时,你有5 + 2 * 5 + 1 = 16个指针,每个8字节,或者1220MB,1000万用户。 当我在d8(V8的开发人员shell)中运行代码并强制GC最终清理剩余的废弃物时,我看到消耗了1258MB。区别在于:
答案 1 :(得分:0)
抱歉,我花了这么长时间才写下来。但似乎我忽略了一些东西。这很尴尬,但我真的没有先看到它。实际上,两个程序在执行期间几乎都需要相同数量的RAM。我的失败是C#代码中User对象的构造函数。
public User(string firstname, string lastname)
{
this.firstName = firstName;
this.lastName = lastName;
}
我分配了&#34; firstName&#34;和&#34; lastName&#34;变量本身而不是传递给构造函数的参数。因为这个错误&#34; firstName&#34;和&#34; lastName&#34;在跑步期间是空的。这当然导致了所需RAM量的减少。
对不起伙计们。但感谢答案。我无法相信我没有看到它。