Да, вы правы. В ряде случаев это отличное решение. Нельзя вообще сказать, что некое решение однозначно плохое или хорошее. Фичи в БД вообще появляются не от капризов «а давайте сделаем вона как!» — это, прежде всего, чья-то насущная необходимость и над ней работало множество умнейших людей. Любая фича проходит множество этапов тестирования и оптимизаций. Это справедливо как для SQL так и для NoSQL. Где-то нужен один набор функциональности, где-то другой. База данных — это не просто хранилище данных. Хранилище данных — это несколько файлов в файловой системе. Вопрос заключается именно в том, как в какой ситуации с этими файлами эффективнее работать? С помощью какого языка эффективнее оперировать с тем набором данных, который представлен? Какая логика лежит в основе? И т.д.
Другими словами, выбор базы данных и используемых в ней средств должно быть мотивировано требованиями. То же самое относится к языкам программирования, операционной системе, железу и т.д.
Лично для меня не существует абстрактного вопроса использовать хранимые процедуры или нет. Использовать можно только где, как и почему. Ровно тоже самое относится и к вопросу SQL против NoSQL. Для меня это вопросы настолько же странные, как вопрос что лучше: шрифты с засечками и без. Говорят, что без засечек теперь популярнее. Что тут можно сказать?
В большинстве проектов, с которыми мне приходилось сталкиваться походу работы, я не встретил ни одного единообразного решения. Были плохие архитектуры, были лучше, были и классические и несколько более неожиданные. Но все они лучше или хуже были адаптированы под конкретную ситуацию. И кстати, если говорить о таких вещах как производительность, надёжность или масштабируемость — то эти вопросы на самом деле являются, как правило, решаемы на любой стадии развития проекта. Вопрос только в цене на железо и иногда на лицензии. И конечно в наличии специалиста (группы), который готов это реализовать. Гуру хранимок сделает всё что угодно на хранимках и это будет хорошо. Другой гуру обойдётся без них, третий сделает то же самое на NoSQL и все эти решения в принципе идентичны. В основном, выбор зависит только от наличия специалиста и какого-то уже имеющегося legasy. Если нет ни того ни другого, то тогда в основном и начинается брожение, так как нет понимания. В этом смысле, на мой взгляд, шумиха вокруг SQL vs NoSQL — война не технологий, а специалистов по этим технологиям.
Если использовать хранимые процедуры, то вычислительная нагрузка на сервер с БД неизбежно увеличится и как результат — она начнет быстрее захлёбываться. Если же запросы формировать в приложении, то его можно легко распараллелить на два и более серверов, что с базой сделать сложнее, особенно когда она уже находится в эксплуатации.
А так же, справедливости ради, стоит заметить, что к примеру в той же Монго хранимые процедуры также поддерживаются, если очень уж надо.
В общем, считаю данное утверждение как минимум спорным.
Вообще идеализировать какое-то отдельное решение не совсем корректно на мой взгляд. По части возможностей NoSQL базы уже не так далеки от своих SQL собратьев. и так просто сравнить их по каким-то точечным характеристикам не так просто. Нужно смотреть на конкретную задачу. В этом смысле в своём коллективе мы предпочитаем классифицировать БД несколько иначе: реляционные, структурные (где хранится json или xml), key-value и raw-stored (один или несколько бинарных файлов, доступ к данным по оффсетам. Довольно удобно для некоторых задач и очень быстро)
Кстати, стоит оговориться, что ключ /standalone появился только в версии pyc.py поставляемой с IronPython 2.7.2. В этой же версии появился zipimport. Версии ниже не поддерживают sys.path.append(r'.\Lib.zip') Пруф
Ух как. Вот этот результат уже очень даже интересен.
00:00:00.1086513
00:00:00.0653087
00:00:00.0619235
00:00:00.0580854
00:00:00.0581689
00:00:00.0563488
00:00:00.0576192
00:00:00.0562254
00:00:00.0565140
00:00:00.0569575
совершенно эквивалентен по скорости полученному в CPython
Немного его переделал:
заменил output.Write(file) на output.Write(file.replace(".", "", 1).replace("\\", "/"))
время замерил с помощью питоньего инструментария
(чтобы мерить одним методом одинаковый функционал с одинаковыми входными и выходными данными)
0:00:00.116000
0:00:00.063000
0:00:00.064000
0:00:00.063000
0:00:00.059000
0:00:00.059000
0:00:00.058000
0:00:00.058000
0:00:00.058000
0:00:00.059000
Немного медленнее, но не раздражает. С учётом того, что в реальности время мериться не будет, соответственно и ресурсы на это тратиться не будут. Уйдет лишний импорт.
Кстати, попробовал в вашем варианте вставить вместо File.OpenRead(fileName) File.ReadAllBytes(fileName) и сразу получил
0:00:00.113000
0:00:00.082000
0:00:00.078000
0:00:00.078000
0:00:00.077000
0:00:00.079000
0:00:00.081000
0:00:00.080000
0:00:00.078000
0:00:00.079000
Не уж-то на столько медленнее? Будет хорошим поводом пройтись по остальному коду приложения…
Спасибо!
С хлещем проще. Собрал новую сборку, прогнал скрипт и все. С версиями пришлось бы контролировать процесс более тщательно для каждого отдельного файла. К тому же, как видите, скрипты сравнительно малы и просты в обоих реализациях. Опять же, в конце концов, на клиенте можно схалтурить и хеш не вычислять или вычислять в случае какой-то особой необходимости. Вместо этого просто сохранять полученный при прошлом обновлении файл с хешами и сравнивать эталон с ним. Хотя это и не очень правильная мысль.
С исключением-то можно и по простому, добавить try-except-else в функцию:
def getMD5sum(fileName):
try:
b = System.IO.File.ReadAllBytes(fileName)
except System.IO.FileNotFoundException:
print 'file ' + fileName + ' deleted'
result = ''
except System.IO.IOException:
print 'file ' + fileName + ' is in use'
result = ''
else:
hash = md5.ComputeHash(b)
hashStr = StringBuilder()
for b in hash:
hashStr.Append(b.ToString("x2"))
result = hashStr.ToString()
return result
Естественно, заменив print'ы на запись в лог.
Ну, а на счёт тестирования на типовом клиентском железе — это конечно же необходимо и обязательно. Нужно будет развернуть несколько виртуалок с разными характеристиками и версиями Windows и погонять там.
Да, масштаб времени не самый удачный. Но сравнить конкретно эти три случая вполне позволяет. Не позволяет, возможно, заметить более тонкую оптимизацию, которую предлагает catlion, но там по всей видимости речь уже будет идти о микросекундах. В данном случае они не сильно показательны. Если бы разница была бы не в сотых долях секунды, а хотя бы в тысячных — был бы смысл.
Да, pypy любопытен. Но к сожалению, мной не разу не использовался, но при случае обязательно проведу сравнение. Очень интересно на сколько верно то, что говорят о его производительности.
Он ведь вроде бы как раз и предназначен для асинхронных запросов к монгодб.
Другими словами, выбор базы данных и используемых в ней средств должно быть мотивировано требованиями. То же самое относится к языкам программирования, операционной системе, железу и т.д.
Лично для меня не существует абстрактного вопроса использовать хранимые процедуры или нет. Использовать можно только где, как и почему. Ровно тоже самое относится и к вопросу SQL против NoSQL. Для меня это вопросы настолько же странные, как вопрос что лучше: шрифты с засечками и без. Говорят, что без засечек теперь популярнее. Что тут можно сказать?
В большинстве проектов, с которыми мне приходилось сталкиваться походу работы, я не встретил ни одного единообразного решения. Были плохие архитектуры, были лучше, были и классические и несколько более неожиданные. Но все они лучше или хуже были адаптированы под конкретную ситуацию. И кстати, если говорить о таких вещах как производительность, надёжность или масштабируемость — то эти вопросы на самом деле являются, как правило, решаемы на любой стадии развития проекта. Вопрос только в цене на железо и иногда на лицензии. И конечно в наличии специалиста (группы), который готов это реализовать. Гуру хранимок сделает всё что угодно на хранимках и это будет хорошо. Другой гуру обойдётся без них, третий сделает то же самое на NoSQL и все эти решения в принципе идентичны. В основном, выбор зависит только от наличия специалиста и какого-то уже имеющегося legasy. Если нет ни того ни другого, то тогда в основном и начинается брожение, так как нет понимания. В этом смысле, на мой взгляд, шумиха вокруг SQL vs NoSQL — война не технологий, а специалистов по этим технологиям.
А так же, справедливости ради, стоит заметить, что к примеру в той же Монго хранимые процедуры также поддерживаются, если очень уж надо.
В общем, считаю данное утверждение как минимум спорным.
Вообще идеализировать какое-то отдельное решение не совсем корректно на мой взгляд. По части возможностей NoSQL базы уже не так далеки от своих SQL собратьев. и так просто сравнить их по каким-то точечным характеристикам не так просто. Нужно смотреть на конкретную задачу. В этом смысле в своём коллективе мы предпочитаем классифицировать БД несколько иначе: реляционные, структурные (где хранится json или xml), key-value и raw-stored (один или несколько бинарных файлов, доступ к данным по оффсетам. Довольно удобно для некоторых задач и очень быстро)
00:00:00.1086513
00:00:00.0653087
00:00:00.0619235
00:00:00.0580854
00:00:00.0581689
00:00:00.0563488
00:00:00.0576192
00:00:00.0562254
00:00:00.0565140
00:00:00.0569575
совершенно эквивалентен по скорости полученному в CPython
Немного его переделал:
заменил output.Write(file) на output.Write(file.replace(".", "", 1).replace("\\", "/"))
время замерил с помощью питоньего инструментария
(чтобы мерить одним методом одинаковый функционал с одинаковыми входными и выходными данными)
0:00:00.116000
0:00:00.063000
0:00:00.064000
0:00:00.063000
0:00:00.059000
0:00:00.059000
0:00:00.058000
0:00:00.058000
0:00:00.058000
0:00:00.059000
Немного медленнее, но не раздражает. С учётом того, что в реальности время мериться не будет, соответственно и ресурсы на это тратиться не будут. Уйдет лишний импорт.
Кстати, попробовал в вашем варианте вставить вместо File.OpenRead(fileName) File.ReadAllBytes(fileName) и сразу получил
0:00:00.113000
0:00:00.082000
0:00:00.078000
0:00:00.078000
0:00:00.077000
0:00:00.079000
0:00:00.081000
0:00:00.080000
0:00:00.078000
0:00:00.079000
Не уж-то на столько медленнее? Будет хорошим поводом пройтись по остальному коду приложения…
Спасибо!
Естественно, заменив print'ы на запись в лог.
Ну, а на счёт тестирования на типовом клиентском железе — это конечно же необходимо и обязательно. Нужно будет развернуть несколько виртуалок с разными характеристиками и версиями Windows и погонять там.