Массив массивов (зубчатые массивы) быстрее, чем многомерные массивы и может использоваться эффективнее. Многомерные массивы имеют более хороший синтаксис.
, Если Вы пишете некоторому простому использованию кода зубчатые и многомерные массивы и затем осматриваете скомпилированный блок с дизассемблером IL, Вы будете видеть, что устройство хранения данных и извлечение от зубчатого (или единственный размерный) массивы являются простыми инструкциями IL, в то время как те же операции для многомерных массивов являются вызовами метода, которые всегда медленнее.
Рассматривают следующие методы:
static void SetElementAt(int[][] array, int i, int j, int value)
{
array[i][j] = value;
}
static void SetElementAt(int[,] array, int i, int j, int value)
{
array[i, j] = value;
}
Их IL будет следующим:
.method private hidebysig static void SetElementAt(int32[][] 'array',
int32 i,
int32 j,
int32 'value') cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: ldelem.ref
IL_0003: ldarg.2
IL_0004: ldarg.3
IL_0005: stelem.i4
IL_0006: ret
} // end of method Program::SetElementAt
.method private hidebysig static void SetElementAt(int32[0...,0...] 'array',
int32 i,
int32 j,
int32 'value') cil managed
{
// Code size 10 (0xa)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: ldarg.2
IL_0003: ldarg.3
IL_0004: call instance void int32[0...,0...]::Set(int32,
int32,
int32)
IL_0009: ret
} // end of method Program::SetElementAt
, Когда использование неровно оборвало массивы, можно легко выполнить такие операции, как подкачка строки и строка изменяют размеры. Возможно, в некоторых случаях использование многомерных массивов будет более безопасным, но даже Microsoft FxCop сообщает, что зубчатые массивы должны использоваться вместо многомерного при использовании его для анализа проектов.
Является ли DEBUG = False в settings.py?
Если нет, Django с радостью сохранит все SQL-запросы, которые вы делаете, которые складываются.
Have you tried gc.set_debug() ?
You need to ask yourself simple questions:
__del__
methods? Do I absolutely, unequivocally, need them?See, the main issue would be a cycle of objects containing __del__
methods:
import gc
class A(object):
def __del__(self):
print 'a deleted'
if hasattr(self, 'b'):
delattr(self, 'b')
class B(object):
def __init__(self, a):
self.a = a
def __del__(self):
print 'b deleted'
del self.a
def createcycle():
a = A()
b = B(a)
a.b = b
return a, b
gc.set_debug(gc.DEBUG_LEAK)
a, b = createcycle()
# remove references
del a, b
# prints:
## gc: uncollectable <A 0x...>
## gc: uncollectable <B 0x...>
## gc: uncollectable <dict 0x...>
## gc: uncollectable <dict 0x...>
gc.collect()
# to solve this we break explicitely the cycles:
a, b = createcycle()
del a.b
del a, b
# objects are removed correctly:
## a deleted
## b deleted
gc.collect()
I would really encourage you to flag objects / concepts that are cycling in your application and focus on their lifetime: when you don't need them anymore, do we have anything referencing it?
Even for cycles without __del__
methods, we can have an issue:
import gc
# class without destructor
class A(object): pass
def createcycle():
# a -> b -> c
# ^ |
# ^<--<--<--|
a = A()
b = A()
a.next = b
c = A()
b.next = c
c.next = a
return a, b, b
gc.set_debug(gc.DEBUG_LEAK)
a, b, c = createcycle()
# since we have no __del__ methods, gc is able to collect the cycle:
del a, b, c
# no panic message, everything is collectable:
##gc: collectable <A 0x...>
##gc: collectable <A 0x...>
##gc: collectable <dict 0x...>
##gc: collectable <A 0x...>
##gc: collectable <dict 0x...>
##gc: collectable <dict 0x...>
gc.collect()
a, b, c = createcycle()
# but as long as we keep an exterior ref to the cycle...:
seen = dict()
seen[a] = True
# delete the cycle
del a, b, c
# nothing is collected
gc.collect()
If you have to use "seen"-like dictionaries, or history, be careful that you keep only the actual data you need, and no external references to it.
I'm a bit disappointed now by set_debug
, I wish it could be configured to output data somewhere else than to stderr, but hopefully that should change soon.
См. это отличное сообщение в блоге Неда Батчелдера о том, как они отследили реальную утечку памяти в Таббло HP. Классика, которую стоит прочитать.
Я думаю, вам следует использовать другие инструменты. По-видимому, полученная вами статистика касается только объектов GC (т.е. объектов, которые могут участвовать в циклах); в частности, в нем отсутствуют строки.
Я рекомендую использовать Pympler ; это должно предоставить вам более подробную статистику.
Do you use any extension? They are a wonderful place for memory leaks, and will not be tracked by python tools.
Попробуйте Guppy .
По сути, вам нужна дополнительная информация или вы сможете ее извлечь. Гуппи даже обеспечивает графическое представление данных.