popkov
Advanced Member | Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору Еще парочка недавно опубликованных фундаментальных глюков Mathematica (проверил присутствие в версиях 5.2 и 7.0.1, но, вероятно, они есть во всех версиях, где есть данные функции). Глюк первый: "зомби" вылезают из Module[]! Как вы думаете, почему MathKernel.exe, даже при выставленном $HistoryLength = 0 , все равно в процессе вычислений (даже если вызывается одна и та же функция, а результаты её работы только экспортируются в файл) постоянно накапливает оперативную память, которую нельзя сбросить (и даже замедлить её наращивание) никакими встроенными функциями? Отчасти на этот вопрос проливает свет недавно обнаруженный баг функции Module[], введенной в версии 2 как альтернатива кривоватому Block[]. Так вот, оказывается, эта функция с легкостью может начать генерировать при каждом её вызове "вечные" мусорные переменные с атрибутом Temporary, в совершенно неограниченном количестве. Причем к каждой такой переменной могут быть привязаны ещё её Definition[] и Attributes[]. Вот уж пример универсальности поговорки: "Нет ничего более постоянного, чем временное (Temporary)!" Рассмотрим "нормальное" поведение Module[]. Определим простую функцию: In[1]:= a[b_] := Module[{c, d}, c := 1; d := 9; d]; Теперь посмотрим, какие переменные появились в текущем контексте: In[2]:= Names[$Context<>"*"] Out[2]= {a,b,c,d} Это - "нормально", т.е. by design. А теперь введем внутрь Module[] условие (Condition[]): In[1]:= a[b_] := Module[{c, d}, c := 1; d := 9; d /; b === 1]; Что же мы имеем теперь в текущем контексте? In[2]:= Names[$Context<>"*"] Out[2]= {a,b,c,c$,d,d$} При введении Condition ("/;") появилась мусорная переменная "c$" c атрибутом Temporary, которая к тому же отказывается удаляться через Remove[c$]. Но она хотя бы не размножается. Переменная "d$" вроде как и правда должна появляться из-за Condition. А теперь посмотрим, что происходит при вызове функции, если условие выполняется: In[3]:= a[1]; Names[$Context <> "*"] {#,ToString[Definition[#]]}&/@Select[%,MemberQ[Attributes[#],Temporary]&]//ColumnForm Out[4]= {a,b,c,c$,d,d$,d$16} Out[5]= {"c$","Attributes[c$] = {Temporary}"} {"d$","Attributes[d$] = {Temporary}"} {"d$16","Attributes[d$16] = {Temporary}"} Если условие в Condition выполняется, происходит генерация "зомби" - мусорных переменных с атрибутом Temporary, которые, согласно документации, должны автоматически удаляться после завершения выполнения Module[]. При каждом выполнении Module[] генерируется новая такая переменная, причем по завершении работы Module[] она не удаляется: In[6]:= Table[a[1],{1000}]; Length@Names[$Context <> "*"] Out[7]= 1007 Надо, правда, признать, что при выставлении $HistoryLength = 0 такое поведение воспроизводится только в том случае, если все вызовы a[1] происходили в одной и той же ячейке (см. последний пример). При выполнении новой ячейки лишние мусорные переменные (кроме c$) и в самом деле удаляются, если $HistoryLength = 0. Однако в практических задачах все вызовы как раз и происходят в пределах одной ячейки, поэтому данный баг вылезает "во всей красе". Следует также напомнить, что Module[] активно используется не только в дополнительных пакетах, поставляемых с системой, но и, несомненно, в высокоуровневом коде втроенных в ядро функций. =============================================== Глюк второй: "шутливый" Compile[]. На этот раз - рандомные результаты работы скомпилированной функции в версиях 5.2 и 7.0.1 (в 8.0 при компиляции возникает runtime error). Вот несколько функций, которые должны возвращать одно и то же. Однако первая из них (самая простая) оказывается с "чувством юмора": abc1 = Compile[{}, Module[{a, b, c}, a = 1.0; b = {1.0, 2.0}; c = {{1.0, 2.0}, {3.0, 4.0}}; a*b*c]]; abc2 = Compile[{}, Module[{a, b, c}, a = 1.0; b = {1.0, 2.0}; c = {{1.0, 2.0}, {3.0, 4.0}}; (a*b)*c]]; abc3 = Compile[{}, Module[{a, b, c}, a = 1.0; b = {1.0, 2.0}; c = {{1.0, 2.0}, {3.0, 4.0}}; a*(b*c)]]; Попробуйте теперь несколько раз последовательно выполнить ячейку: abc1[] abc2[] abc3[] и сравните результаты! | Всего записей: 1833 | Зарегистр. 22-03-2003 | Отправлено: 20:17 09-12-2010 | Исправлено: popkov, 20:24 09-12-2010 |
|