{ "info": { "author": "Emin Martinian", "author_email": "emin.martinian@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Programming Language :: Python :: 3" ], "description": "Introduction\n============\n\nThe ``ox_profile`` package provides a python framework for statistical\nprofiling. If you are using ``Flask``, then ``ox_profile`` provides a\nflask blueprint so that you can start/stop/analyze profiling from within\nyour application. You can also run the profiler stand-alone without\n``Flask`` as well.\n\nTo learn more, you can browse the overview slides in `PDF\nform `__\nor read more details below.\n\nWhy statistical profiling (and why ox\\_profile)?\n================================================\n\nPython contains many profilers which instrument your code and give you\nexact results. A main benefit here is you know *exactly* what your\nprogram is doing. The disadvantage is that there can be significant\noverhead. With a statistical profiler such as ``ox_profile``, we sample\na running program periodically to get a sense of what the program is\ndoing with an overhead that can be tuned as desired.\n\nOne main use case for ``ox_profile`` specifically (and statistical\nprofiling in general) is that you can apply it to a production server to\nsee how things work \"in the wild\".\n\nThere are other statistical profilers out there for python (such as\nstatprof), which are pretty good and may be better for your needs than\n``ox_profile``. So why would you consider ``ox_profile``? Some possible\nreasons include:\n\n1. Works on non-UNIX systems (e.g., works on Windows).\n\n - Many other statistical profilers use various excellent features of\n LINUX or UNIX while ``ox_profile`` only really relies on the\n python ``sys._current_frames`` method.\n\n2. Simple to understand.\n\n - The code for ``ox_profile`` is fairly simple. The main work is\n really inside ``ox_profile.core.sampling.Sampler`` so it is easy\n to reason about or modify if you need slightly different\n profiling.\n\n3. Flask Blueprint provided.\n\n - If you are using Flask, then you can register the ``ox_profile``\n blueprint and easily get statistical profiling in your flask app.\n\nUsage\n=====\n\nStand alone\n-----------\n\nYou can install ``ox_profile`` using pip via something like\n\n.. code:: sh\n\n $ pip install ox_profile\n\nThe simplest way to run the profiler is by starting the launcher,\ncalling some functions, and the printing the profiled data via something\nlike:\n\n::\n\n >>> from ox_profile.core.launchers import SimpleLauncher\n >>> profiler = SimpleLauncher.launch() # Create and start a profiler.\n >>> # call some functions\n >>> print(profiler.show()) # Print current results in preformated way.\n >>> profiler.cancel() # Turns off the profiler for good.\n\nOften you may want a slightly more sophisticated use case where you can\npause and unpause the profiler and get more details about its status as\nshown below:\n\n::\n\n >>> from ox_profile.core import launchers\n >>> profiler = launchers.SimpleLauncher() # Create an instance of launcher to be your profiler\n >>> profiler.start() # The profiler is a thread so we need to call start\n >>> profiler.unpause() # The profiler starts out paused so we unpause it\n >>> # call functions or start main program\n >>> profiler.pause() # You can pause if done profiling or leave running\n >>> query, total_records = profiler.query() # Query for what the profiler has found\n >>> info = ['%s: %s' % (i.name, i.hits) for i in query]\n >>> print('Items in query:\\n - %s' % (('\\n - '.join(info))))\n >>> profiler.cancel() # This turns off the profiler for good\n\nWith Flask\n----------\n\nIf you are using the python flask framework and have installed\n``ox_profile`` (e.g., with ``pip install ox_profile``) then you can\nsimply do the following in the appropriate place after initializing your\napp:\n\n::\n\n from ox_profile.ui.flask.views import OX_PROF_BP\n app.register_blueprint(OX_PROF_BP)\n app.config['OX_PROF_USERS'] = {, , ...}\n\nwhere ````, etc. are strings referring to users who are\nallowed to access ``ox_profile``.\n\nPointing your browser to the route ``/ox_profile/status`` will then show\nyou the profiling status. By default, ``ox_profile`` starts out paused\nso that it will not incur any overhead for your app. Go to the\n``/ox_profile/unpause`` route to unpause and begin profiling so that\n``/ox_profile/status`` shows something interesting.\n\nOutput\n======\n\nCurrently ``ox_profile`` is in alpha mode and so the output is fairly\nbare bones. When you look at the results of calling the ``query`` method\nof an instance of ``SimpleLauncher`` in stand alone mode or at the\n``/ox_profile/status`` route when running with flask, what you get is a\nraw list of each function your program has called along with how many\ntimes that function was called in our sampling.\n\nDesign\n======\n\nHigh Level Design\n-----------------\n\nPython offers a number of ways to get profiling information. In addition\nto high-level profiling tools such as in the ``profile`` package, there\nare specialized functions like ``sys.settrace`` and ``sys.setprofile``.\nThese are used for deterministic profiling and relatively robust but\nhave some overhead as they are invoked on each function call.\n\nAt a high level, we want a way to get a sample of what the python\ninterpreter is doing at any give instance. The sampling approach has the\nadvantage that by turning the sampling interval low enough, we can add\narbitrarily low overhead and make profiling feasible in a production\nsystem. By taking a long enough sample, however, we should be able to\nget arbitrarily accurate profiling information.\n\nLow Level Design\n----------------\n\nAt a low level, we do this sampling using ``sys._current_frames``. As\nsuggested by the leading underscore, this system function may be a bit\nless robust. Indeed, the documentation says \"This function should be\nused for specialized purposes only.\" Hopefully the core python\ndevelopers will not make major changes to such a useful function.\n\nIn any case, the most interesting class is the ``Sampler`` class in the\n``ox_profile.core.sampling`` module. This class has a run method which\ndoes the following:\n\n1. Uses ``sys.setswitchinterval`` to try and prevent a thread context\n switch.\n2. Calls ``sys._current_frames`` to sample what the python interpreter\n is doing.\n3. Updates a simple in-memory database of what functions are running.\n\nIn principle, you could just use the Sampler via something like\n\n::\n\n >>> from ox_profile.core import sampling, recording\n >>> sampler = sampling.Sampler(recording.CountingRecorder())\n >>> def foo():\n ... sampler.run()\n ... return 'done'\n ... \n >>> foo()\n\nThe above would have the sampler take a snapshot of the stack frames\nwhen the ``foo`` function is run. Of course, this isn't very useful by\nitself because it just tells you that ``foo`` is being run. It could be\nuseful if there were other threads which were running because the\nsampler would tell you what stack frame those threads were in.\n\nIn principle, you could just call the ``Sampler.run`` method to track\nother threads but that still isn't very convenient. To make things easy\nto use, we provide the ``SimpleLauncher`` class in the\n``ox_profile.core.launchers`` module as shown in the Usage section. The\n``SimpleLauncher`` basically does the following:\n\n1. Creates an instance of the ``Sampler`` class with reasonable\n defaults.\n2. Initializes itself as a daemon thread and starts.\n3. Pauses itself so the thread does nothing so as to not load the\n system.\n4. Provides an ``unpause`` method you can use when you want to turn on\n profiling.\n5. Provides a ``pause`` method if you want to turn off profiling.\n\nIn principle, you don't need much beyond the ``Sampler`` but the\n``SimpleLauncher`` makes it easier to launch a ``Sampler`` in a separate\nthread.\n\nKnown Issues\n============\n\nGranularity\n-----------\n\nWith statistical profiling, we need to ask the thread to sleep for some\nsmall amount so that it does not overuse CPU resources. Sadly, the\nminimum sleep time (using either ``time.sleep`` or ``wait`` on a thread\nevent) is on the order of 1--10 milliseconds on most operating systems.\nThis means that you can not efficiently do statistical profiling at a\ngranularity finer than about 1 millisecond.\n\nThus you should consider statistical profiling as a tool to find the\nrelatively slow issues in production and not a tool for optimizing\nissues faster than about a millisecond.\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/emin63/ox_profile", "keywords": "statistical profiling", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "ox_profile", "package_url": "https://pypi.org/project/ox_profile/", "platform": "", "project_url": "https://pypi.org/project/ox_profile/", "project_urls": { "Homepage": "http://github.com/emin63/ox_profile" }, "release_url": "https://pypi.org/project/ox_profile/0.2.5/", "requires_dist": null, "requires_python": "", "summary": "Tools for statistical profiling.", "version": "0.2.5" }, "last_serial": 5504370, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "1da2112f2bda444ab4553cacdf129b3f", "sha256": "e234ae6820d06923ced5f0821bf61d7998cc2ef01d82117b5b6168410fb2a02d" }, "downloads": -1, "filename": "ox_profile-0.1.0.tar.gz", "has_sig": false, "md5_digest": "1da2112f2bda444ab4553cacdf129b3f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3528, "upload_time": "2017-09-20T18:24:05", "url": "https://files.pythonhosted.org/packages/e0/88/870282c104ab552b07c77c2b6e8bb2ab801d011ff55e2abd2c1a503ee163/ox_profile-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "0172c1e25b3e2f5b1c6ab1e449aed378", "sha256": "87ae77ab486d0d43e2b861b2ea12dd5c1aab8437c397cb366cd5a9773c50672e" }, "downloads": -1, "filename": "ox_profile-0.1.1.tar.gz", "has_sig": false, "md5_digest": "0172c1e25b3e2f5b1c6ab1e449aed378", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3430, "upload_time": "2017-09-20T18:24:58", "url": "https://files.pythonhosted.org/packages/e8/81/51a36a26cf51a72754fc3fbe06b725c5842545810eccc133ed0b6c5f3901/ox_profile-0.1.1.tar.gz" } ], "0.1.10": [ { "comment_text": "", "digests": { "md5": "240a7630cdc3ec5ede997e4b05199271", "sha256": "532fc34c02a2d0e531c473cc66aa637b213b4f3e110862ecbb935a7361c3cbe7" }, "downloads": -1, "filename": "ox_profile-0.1.10.tar.gz", "has_sig": false, "md5_digest": "240a7630cdc3ec5ede997e4b05199271", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12522, "upload_time": "2017-10-12T01:02:14", "url": "https://files.pythonhosted.org/packages/ca/60/3deb5127e938958fba392b0b86bb7444b1095a9e26960f969e04ce11a90d/ox_profile-0.1.10.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "6bd9d45874ec1a6adaa98700c33ef95d", "sha256": "82ba20dd8af9592a165a2494992a8c1fd9de24dac5744d335803f0a9ccb0b435" }, "downloads": -1, "filename": "ox_profile-0.1.2.tar.gz", "has_sig": false, "md5_digest": "6bd9d45874ec1a6adaa98700c33ef95d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5170, "upload_time": "2017-09-20T18:49:00", "url": "https://files.pythonhosted.org/packages/83/bf/459068d9e655357f1e2a6bdeec4173915a3e9ba732c296a6b422ac55a0bf/ox_profile-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "0789a1dc3228b679479249871515dd8d", "sha256": "dbd01a374455d39527541ecc26d1d5eb3564bdec3106d84ce9b574c160036830" }, "downloads": -1, "filename": "ox_profile-0.1.3.tar.gz", "has_sig": false, "md5_digest": "0789a1dc3228b679479249871515dd8d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9305, "upload_time": "2017-09-20T19:07:44", "url": "https://files.pythonhosted.org/packages/60/74/488f2a1313913ccd95fda753e169d0f358a352beeb86be3c0a23a762fad7/ox_profile-0.1.3.tar.gz" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "8ce8d8b8078ebf53819ef622240a8434", "sha256": "2eff991e1e428517fd7fd9e4f5d2fff04a7e6ab7c1b0047b47920e9bf80fbecd" }, "downloads": -1, "filename": "ox_profile-0.1.4.tar.gz", "has_sig": false, "md5_digest": "8ce8d8b8078ebf53819ef622240a8434", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9311, "upload_time": "2017-09-22T21:14:48", "url": "https://files.pythonhosted.org/packages/fd/09/3df0e9235ad658c79dfeb752f5092987aa789a140f72724b32682f3d61ce/ox_profile-0.1.4.tar.gz" } ], "0.1.5": [ { "comment_text": "", "digests": { "md5": "13435f5e9d304c9e6680c1feb971f115", "sha256": "20d31372ee154dd2c012e1a470763edaf2047a67d8b0748b81126de7d66c2ada" }, "downloads": -1, "filename": "ox_profile-0.1.5.tar.gz", "has_sig": false, "md5_digest": "13435f5e9d304c9e6680c1feb971f115", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10644, "upload_time": "2017-09-22T21:22:29", "url": "https://files.pythonhosted.org/packages/e0/2b/8a6b62908f8f47eaa851ed94850cc92bb90f0d1db5348405d121c9461826/ox_profile-0.1.5.tar.gz" } ], "0.1.6": [ { "comment_text": "", "digests": { "md5": "11b8a0272ff3e4131768d946b7af743d", "sha256": "166c1229ac45ab54db9f7e7a94ea826f2d384bc706e1f0cc5af17da32f481018" }, "downloads": -1, "filename": "ox_profile-0.1.6.tar.gz", "has_sig": false, "md5_digest": "11b8a0272ff3e4131768d946b7af743d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10660, "upload_time": "2017-09-22T21:28:39", "url": "https://files.pythonhosted.org/packages/47/cc/6d2b7aafb756aa5515ce927e333b6acab7e11dde08de5e79aaa49f664de6/ox_profile-0.1.6.tar.gz" } ], "0.1.7": [ { "comment_text": "", "digests": { "md5": "3ebbafc2b7a42f35d4d5af0cf0c86348", "sha256": "53d6906e668e64bbbbb259d49298685b9b60db61b15ed4931e76122e9bb1d500" }, "downloads": -1, "filename": "ox_profile-0.1.7.tar.gz", "has_sig": false, "md5_digest": "3ebbafc2b7a42f35d4d5af0cf0c86348", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10718, "upload_time": "2017-10-10T19:52:13", "url": "https://files.pythonhosted.org/packages/f4/e4/207f51cddcb44a01846ea1600c7e6cbfbd043a11e3ddd59de8ffdc3f0c59/ox_profile-0.1.7.tar.gz" } ], "0.1.8": [ { "comment_text": "", "digests": { "md5": "9702ae7ace45658c497de2b2e1017962", "sha256": "5364f2deca30abeb252b819aff7b8cf397bbc5fb03e8dc46c85320688b8961eb" }, "downloads": -1, "filename": "ox_profile-0.1.8.tar.gz", "has_sig": false, "md5_digest": "9702ae7ace45658c497de2b2e1017962", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10909, "upload_time": "2017-10-11T03:12:29", "url": "https://files.pythonhosted.org/packages/33/f0/83c86f30f9c4bdcaff0e6cd74082d2cc514fb9e197e03350a3aedda139ca/ox_profile-0.1.8.tar.gz" } ], "0.1.9": [ { "comment_text": "", "digests": { "md5": "1897d317a00d4d9ae07831594815537a", "sha256": "1aa4705dd7bdf4c354f7261a24ff99f5de6941e26b69d93dc6f69fcc3e62309f" }, "downloads": -1, "filename": "ox_profile-0.1.9.tar.gz", "has_sig": false, "md5_digest": "1897d317a00d4d9ae07831594815537a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11056, "upload_time": "2017-10-11T03:46:29", "url": "https://files.pythonhosted.org/packages/ff/38/add2128c9a6f98000890512b62efe97f00bc16e031aef1ae69bc5de3490c/ox_profile-0.1.9.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "fd88dc507d1cfbd68c5e263ced2684f2", "sha256": "2178655f79f1c45ed07e90c8c358a446abcbd31c0a996d30286a8f0b7cf54a61" }, "downloads": -1, "filename": "ox_profile-0.2.0.tar.gz", "has_sig": false, "md5_digest": "fd88dc507d1cfbd68c5e263ced2684f2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12548, "upload_time": "2018-06-09T01:16:19", "url": "https://files.pythonhosted.org/packages/e3/60/abd2e50627d2386ee2e6e0741551783b0e56374b2f64120589f7357e671d/ox_profile-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "fcbfd74f327f9a73bea299796e4d6916", "sha256": "a3fe4af557ac9b4104f4044c184e02309273264e7a6ae2f4558f61649b0d80b9" }, "downloads": -1, "filename": "ox_profile-0.2.1.tar.gz", "has_sig": false, "md5_digest": "fcbfd74f327f9a73bea299796e4d6916", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15975, "upload_time": "2018-10-12T20:10:00", "url": "https://files.pythonhosted.org/packages/11/cc/94af77d3d1dcd89de9d271a4f544ff3d8edbc9cedffe7beffd6faf40e7ff/ox_profile-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "4625d4b04ec5a9a291117102c5046dad", "sha256": "956184d6155ef7e6a653b81e42a1d463114de93fc1116d36f055a5ac36e0ebc1" }, "downloads": -1, "filename": "ox_profile-0.2.2.tar.gz", "has_sig": false, "md5_digest": "4625d4b04ec5a9a291117102c5046dad", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17369, "upload_time": "2018-10-12T20:22:28", "url": "https://files.pythonhosted.org/packages/97/02/d710242f9f681da516fa4c15316e98cde160ac343d38f7ab708c8b355720/ox_profile-0.2.2.tar.gz" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "84c7bfb8026f3cca0885156e63d73cc9", "sha256": "b0466ea3c672b1f4232a5d75e3d0d2a0be24f0c4df82ebe61761b333085ee786" }, "downloads": -1, "filename": "ox_profile-0.2.3.tar.gz", "has_sig": false, "md5_digest": "84c7bfb8026f3cca0885156e63d73cc9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18758, "upload_time": "2018-10-12T20:40:06", "url": "https://files.pythonhosted.org/packages/49/b3/7647f5e4803da2686a6614104135108e96cd80a67136dfe20425c53619b9/ox_profile-0.2.3.tar.gz" } ], "0.2.4": [ { "comment_text": "", "digests": { "md5": "7624ffbeb6192d34f756bc9ac35ecb62", "sha256": "10e9cfdfb7d51c241b33fd3314123aeba10103fe41a22d958386f9f3ac1fb5da" }, "downloads": -1, "filename": "ox_profile-0.2.4.tar.gz", "has_sig": false, "md5_digest": "7624ffbeb6192d34f756bc9ac35ecb62", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18742, "upload_time": "2018-10-12T20:42:28", "url": "https://files.pythonhosted.org/packages/20/00/3c6560290d4a125b68e0dacb2176468c6fe3634bf460e6dca4099d710feb/ox_profile-0.2.4.tar.gz" } ], "0.2.5": [ { "comment_text": "", "digests": { "md5": "5daba18add381c4c6d087c1c7253e2f1", "sha256": "2f44ec959011efc9316319c1874d2dc36014136547721631cb311514a4b2d660" }, "downloads": -1, "filename": "ox_profile-0.2.5.tar.gz", "has_sig": false, "md5_digest": "5daba18add381c4c6d087c1c7253e2f1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20870, "upload_time": "2019-07-09T02:22:19", "url": "https://files.pythonhosted.org/packages/f4/45/350688929fc5a60f1f5074410445f19db3818eba68fee8f5e952e5ba97de/ox_profile-0.2.5.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "5daba18add381c4c6d087c1c7253e2f1", "sha256": "2f44ec959011efc9316319c1874d2dc36014136547721631cb311514a4b2d660" }, "downloads": -1, "filename": "ox_profile-0.2.5.tar.gz", "has_sig": false, "md5_digest": "5daba18add381c4c6d087c1c7253e2f1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20870, "upload_time": "2019-07-09T02:22:19", "url": "https://files.pythonhosted.org/packages/f4/45/350688929fc5a60f1f5074410445f19db3818eba68fee8f5e952e5ba97de/ox_profile-0.2.5.tar.gz" } ] }