Дифференциальная реализация ответа @cosmosis. Вероятно, это более гибко.
import numpy as np
import matplotlib.pyplot as plt
X = np.linspace(0,100,11)
plt.plot(X,-X, label='plot 1', color='red')
plt.plot(X,-2*X, label='plot 2', color='green')
plt.plot(X,-3*X, label='plot 3', color='blue')
(lines, labels) = plt.gca().get_legend_handles_labels()
#it's safer to use linestyle='none' and marker='none' that setting the color to white
#should be invisible whatever is the background
lines.insert(1, plt.Line2D(X,X, linestyle='none', marker='none'))
labels.insert(1,'')
plt.legend(lines,labels,numpoints=1, loc=4,ncol=1)
plt.show()
Другой вариант - создать две легенды в качестве здесь , а затем вытеснить их с помощью ключевого слова bbox_to_anchor здесь
(lines, labels) = plt.gca().get_legend_handles_labels()
leg1 = plt.legend(lines[:1], labels[:1], bbox_to_anchor=(0,0,0.8,1), loc=1)
leg2 = plt.legend(lines[1:], labels[1:], bbox_to_anchor=(0,0,1,1), loc=1)
gca().add_artist(leg1)
Выполняя это, я получаю [/g2] без необходимости добавления каких-либо других объектов.
Как уже ответила пара других людей, просто для удовольствия, вот очень быстрый тест (смею ли я его так называть?) ; рассмотрите следующий код:
$num = 1;
$list = array_fill(0, 5000, str_repeat('1234567890', $num));
$before = microtime(true);
for ($i=0 ; $i<10000 ; $i++) {
$str = serialize($list);
}
$after = microtime(true);
var_dump($after-$before);
var_dump(memory_get_peak_usage());
Я запускаю это на PHP 5.2.6 (тот, который идет в комплекте с Ubuntu jaunty).
И да, есть только значения; нет ключей; и значения довольно просты: нет объекта, нет подмассивов, нет ничего, кроме строки.
Для $ num = 1
вы получите:
float(11.8147978783)
int(1702688)
Для $ num = 10
, вы получите:
float(13.1230671406)
int(2612104)
А для $ num = 100
вы получите:
float(63.2925770283)
int(11621760)
Таким образом, кажется, что чем больше каждый элемент массива, тем больше времени требуется ( на самом деле кажется справедливым) . Но для элементов в 100 раз больше у вас не потребуется в 100 раз больше времени ...
Теперь с массивом из 50000 элементов вместо 5000, это означает, что эта часть кода изменена:
$list = array_fill(0, 50000, str_repeat('1234567890', $num));
С $ num = 1
вы получите:
float(158.236332178)
int(15750752)
Учитывая время, которое потребовалось для 1, я не буду запускать это ни для $ num = 10 или $ num = 100 ...
Да, конечно, в реальной ситуации вы бы не сделали это 10 000 раз; поэтому давайте попробуем выполнить только 10 итераций цикла for.
Для $ num = 1
:
float(0.206310987473)
int(15750752)
Для $ num = 10
:
float(0.272629022598)
int(24849832)
И для $ num = 100
:
float(0.895547151566)
int(114949792)
Да, это почти 1 секунда - и используется довольно много памяти ^^
(Нет, это не рабочий сервер: у меня довольно высокий предел memory_limit на этой машине разработки ^^)
Итак, в конце концов, он должен быть немного короче, чем это число - и, да, у вас могут быть числа, которые говорят все, что вы хотите - Я бы не сказал, что есть «предел», как в «жестко запрограммированном» в PHP, но вы в конечном итоге столкнетесь с одним из них:
max_execution_time
(обычно на веб-сервере не более 30 секунд) memory_limit
(на веб-сервере обычно не более 32 МБ) Но,
И вы должны принять во внимание количество времени / загрузки процессора, использование этого кеша может помочь вам; -)
Тем не менее, лучший способ узнать это - провести тестирование самостоятельно, с реальными данными ;-)
И вы можете также посмотреть, что Xdebug может сделать, когда дело доходит до профилирования : такая ситуация - одна из тех, для которых она полезна!
Функция serialize () ограничена только доступной памятью.
PHP не применяет ограничений. Serialize возвращает представление байтового потока (строку) сериализованной структуры, поэтому вы просто получите большую строку.
Единственным практическим ограничением является доступная память, поскольку сериализация включает создание строки в памяти.
Хорошо ... еще номера! (PHP 5.3.0 OSX, без кеша опкодов)
Код @Pascal на моей машине для n = 1 при 10 тыс. Итерах дает:
float(18.884856939316)
int(1075900)
Я добавляю unserialize () к вышеприведенному, так что
$num = 1;
$list = array_fill(0, 5000, str_repeat('1234567890', $num));
$before = microtime(true);
for ($i=0 ; $i<10000 ; $i++) {
$str = serialize($list);
$list = unserialize($str);
}
$after = microtime(true);
var_dump($after-$before);
var_dump(memory_get_peak_usage());
производит
float(50.204112052917)
int(1606768)
Я предполагаю, что лишние 600 КБ или около того - это сериализованная строка.
Мне было интересно узнать о var_export и его партнере include / eval $ str = var_export ($ list, true);
вместо serialize () в оригинал производит
float(57.064643859863)
int(1066440)
, поэтому памяти становится немного меньше (по крайней мере, для этого простого примера), но уже больше времени.
добавление в eval ('$ list ='. $ str. ';');
вместо unserialize в приведенном выше производит
float(126.62566018105)
int(2944144)
Указывает, что, вероятно, есть утечка памяти где-то при выполнении eval: - /.
Итак, опять же, это не ' отличные тесты (мне действительно нужно изолировать eval / unserialize, поместив строку в локальную переменную или что-то в этом роде, но я ленив), но они показывают связанные тенденции. var_export кажется медленным.
Нет ограничений, но помните, что сериализация и десериализация имеет свои затраты.
Десериализация чрезвычайно дорога.
Менее затратный способ кэширования этих данных будет через var_export ()
как таковой (начиная с PHP 5.1.0, он работает с объектами ):
$largeArray = array(1,2,3,'hello'=>'world',4);
file_put_contents('cache.php', "<?php\nreturn ".
var_export($largeArray, true).
';');
Затем вы можете просто получить массив, выполнив следующие действия:
$largeArray = include('cache.php');
Ресурсы обычно не могут быть кэшированы.
К сожалению, если в вашем массиве есть циклические ссылки, вам нужно использовать ] serialize ()
.
Нет, ограничений нет, и это :
set_time_limit(0);
ini_set('memory_limit ', -1);
unserialize('s:2000000000:"a";');
поэтому у вас должен быть safe.mode = On или установленное расширение, подобное Suhosin , иначе оно займет всю память в вашей системе.
Если вы хотите кэшировать его (поэтому я предполагаю, что проблема в производительности), используйте вместо него apc_add, чтобы избежать снижения производительности при преобразовании его в строку + кеш-память в памяти.
Как указано выше, единственное ограничение на размер - доступная память.
Несколько других ошибок: сериализованные данные не переносятся между многобайтовыми и однобайтовыми кодировками символов. Классы PHP5 включают байты NUL, которые могут вызвать хаос с кодом, который их не ожидает.
Похоже, что вам лучше использовать базу данных, чем полагаться исключительно на доступные ресурсы PHP. Преимущества использования чего-то вроде MySQL в том, что он специально разработан с учетом управления памятью для таких вещей, как хранение и поиск.
На самом деле неинтересно постоянно сериализовать и десериализовать данные только для обновления или изменения некоторых фрагментов информации.
Я думаю, что лучше, чем сериализация, - это функция json_encode . У него есть недостаток, заключающийся в том, что ассоциативные массивы и объекты не различаются, но строковый результат меньше и легче читается человеком, поэтому его также можно отлаживать и редактировать.