В 64-битной Java каждый экземпляр объекта имеет тенденцию включать 192-битный заголовок , содержащий
- указатель класса,
- флаги и
- замки (по 64 бита).
Это может вызвать большие накладные расходы памяти для небольших объектов.
Схожа ли ситуация для Нима? Будет ли большое приложение (где размер среды выполнения незначительным), написанное одинаково на двух языках, использовать примерно одинаковый объем памяти?
Обновление
Я провел несколько экспериментов, в которых я строил наивный односвязный список из 100M float64
элементов и многократно повторял его.
Java фактически использует 25% меньше памяти, чем Nim, согласно htop
.
Полный код Nim:
type Node = ref object
data : float64
next : Node
echo "Running"
proc create(n : int): Node =
var
tmp = Node(data: 0, next: nil)
for i in 1..<n:
tmp = Node(data: i.float64, next: tmp)
return tmp
proc sum(x: Node): float64 =
var
tmp: float64 = 0
y = x
while true:
tmp += y.data
y = y.next
if y.isNil:
return tmp
proc sums(x: Node, n: int): float64 =
var tmp: float64 = 0
for i in 0..<n:
tmp += sum(x) / n.float64
return tmp
let x = create(1000 * 1000 * 100)
echo "Created"
echo sums(x, 100)
echo "Finished"
Используется 3,1 ГБ, что соответствует 269 битам на Node
, тогда как Java использует 203 бит на Node
в очень похожем коде. Это меньше чем 192-битный заголовок + 128-битная структура. Я предполагаю, что какая-то JIT-оптимизация заставляет Java работать, используя меньше памяти.
Полный код Java:
Node.java
public class Node {
double data = 0;
Node next = null;
}
SListTest.java
public class SListTest {
static Node create(int n) {
Node tmp = new Node();
for(int i = 1; i < n; ++i) {
Node p = new Node();
p.data = i;
p.next = tmp;
tmp = p;
}
return tmp;
}
static double sum(Node x) {
double tmp = 0;
while(x != null) {
tmp += x.data;
x = x.next;
}
return tmp;
}
static double sums(Node x, int n) {
double tmp = 0;
for(int i = 0; i < n; ++i)
tmp += sum(x);
return tmp / n;
}
public static void echo(String s) {
System.out.println(s);
System.out.flush();
}
public static void main(String[] args) {
echo("Started");
Node p = create(1000 * 1000 * 100);
echo("Created");
double tmp = sums(p, 100);
System.out.printf("%f\n", tmp);
echo("Finished");
}
}