$ npm install crystal -g
The option -g
installs crystal
globally so you can run crystal
from any directory.
Crystal is a fully customizable metaprogramming engine that:
uses high level specifications and low level generators to help you build apps, websites and other software for any programming language
is meant to be used on an ongoing basis beyond project creation
allows multiple generators to be added (or removed) to a project or another generator at anytime
has its own built-in package manager so you can easily search, install and update generators
allows you to create your own generators
allows you to publish generators for others to use
uses a standardized specification
allows additional specifications when creating generators
makes language integration and migration easier
Once installed, crystal
runs as a CLI program.
Note: be sure to install crystal
with the -g
option to ensure it is installed globally and can be used for any directory.
crystal
accepts the commands and arguments below.
Required arguments are surrounded by tags <>
and optional arguments are surrounded by brackets []
.
If a command accepts the dir
argument and no dir
is specified, it uses the current working directory.
Note: Commands that use the dir
argument are looking for a Crystal Config file.
# build project from current or specified directory
crystal build [dir]
# read/write value from/to cache
crystal cache key [value]
# clean project from current or specified directory
crystal clean [dir]
# get or set default value
crystal default [key] [value]
# get help
crystal help
# initialize a crystal project
crystal init [dir]
# install a generator
crystal install <generator>
# publish project from current or specified directory
crystal publish [dir]
# run project from current or specified directory
crystal run [dir]
# search for public generators
crystal search <generator>
# signup for crystal
crystal signup
# run tests for generator
crystal test
# update generators for project
crystal update
# update project version
crystal version <major|minor|patch>
There are many ways to use crystal
but the two most common scenarios are:
crystal
for your projectscrystal
to create generatorscrystal
is powerful. It has several generators to choose from and helps you bootstrap your projects in no time.
But it doesn't stop there. crystal
is meant to be used for projects on an ongoing basis. It helps you deliver high quality code for every story, every sprint and every epic. It's there for launch, maintenance and upgrades.
If you are happy using crystal
to make robust apps (or save the world), then use it for your projects and enjoy the generators made by the wonderful community of crystal
.
If you haven't found the right one. Or if you could do it better. Or just want to give a whirl:
Try creating a generator for you favorite language, framework or even your own custom code.
Generators are projects that are meant to be used as generators. In other words, a project is a project unless it:
gen
key in the Crystal Config Filegen
folder in the Crystal Source Directory (default: ./src
)Once this has been done, the crystal
project can then be used a generator for other projects. Or generators. Or itself.
If you want to share it with the world, then you'll also need to:
/src/test
)crystal publish
Below are all of the folders that can be used by crystal
.
Note: The only required file is a Crystal Config File (default: crystal.yml
).
lib/
- output directory (where generators push to)src/
- source directory (where generators pulls from)code/
- code filesdoc/
- documentation files$chapter_name
- name of a chapter$page_name
- name of a pagegen/
- gen files used for generators$gen_file.hbs
a generator filespec/
- spec files that describe the projectmodel/
$model_name.yml
- name of a modelcrystal.yml
- crystal config fileIn order for your project to properly integrate with crystal
, a config file must be added to a directory in your project (preferably in the project's root directory).
It can be created in the following formats:
Discovery of this file happens in the following order:
crystal.yml
crystal.yaml
crystal.cson
crystal.json
crystal.xml
For example, if you had both a crystal.yml
file and crystal.cson
file, only the crystal.yml
would be loaded.
The only required fields in the crystal config file are name:
and version:
. Everything else is optional.
Adding crystal
to a new project is easy.
Adding crystal
to an existing project is as easy as adding it to a new project.
The options below can be used for the Crystal Config File:
# the project's name (required)
name:
# the project's version, must be semver 2.0 compliant (required)
version:
# the project's description (required)
description:
# true or false
private:
# the chief author's name, email & url
author:
name:
email:
url:
# the project's copyright (example: 2015 Acme, Inc.)
copyright:
# the project's documentation
doc:
$chapter-name:
title: # the chapter's title
pages:
$page-name:
title: # the page's title
# the project's repository
repository:
type: # git or svn
url:
# the project's generator
gen:
file:
$file: # name of the file (without the extension)
dest: # the destination of the file, use '.' for root (default: lib)
mapping:
model:
details:
name:
format:
case: '<camel|lower|proper|upper>' (lowercase)
spacing: '<dash|none|underscore>' (underscore)
type:
bool: <'DETAIL_TYPE'|false>
date: <'DETAIL_TYPE'|false>
decimal: <'DETAIL_TYPE'|false>
image: <'DETAIL_TYPE'|false>
model: <'DETAIL_TYPE'|false>
number: <'DETAIL_TYPE'|false>
string: <'DETAIL_TYPE'|false>
time: <'DETAIL_TYPE'|false>
name:
format:
case: '<camel|lower|proper|upper>'
spacing: '<dash|none|underscore>'
spec: # custom spec
$field_name: # add custom field with unique name
required: <true|false>
type: '<option|string>'
# the generators used by the project (yes, generators can use other generators)
generators:
$generator_name: # add generator by name
pass: set to `true` to skip this generator when used by another generator (pass to projects that use this generator instead)
path: # the path used for the generator's output (the default is 'lib')
spec: # spec variables to pass to the generator
version: # the version of the generator to be used
# languages based on generator's output
languages: # optional
- <csharp|go|java|js|nodejs|php|python|ruby|other>
# scripts ran for specific commands
scripts:
build:
- $cmd # example - npm update
run:
- $cmd
test:
- $cmd
The Directory Structure for the spec is like:
# usage
- model/
- $model_name.$model_format
# example
- model/
- order.yml
- product.yml
- user.yml
Each file has the following options:
Config Variables are defined in the Crystal Config File and can be used at any level within the document.
{{@name}} string
{{@version}} string
{{@description}} string
{{@private}} bool
{{@author}} object
<EMAIL_ADDRESS>string
<EMAIL_ADDRESS>string
<EMAIL_ADDRESS>string
{{@copyright}} string
{{@repository}} object
<EMAIL_ADDRESS>string
<EMAIL_ADDRESS>string
# model
{{model}}
{{$model_name}} object
Generators generate code.
Some are big and produce entire libraries for Restful APIs, models and other robust services. Others are small and only produce a single file such as a README.md, AUTHORS or .gitignore file.
They can work together or alone. They can have one purpose or many. They can be public or private. And they can be created from scratch or added to an existing project.
Generators are what make crystal
useful to you and others. So use them. Make them. Make a lot of them. Then make generators for your generators and generators for your generators' generators.
Loading generators is easy and can happen in a few ways.
Usually generators are added to your project's crystal config such as this readme generator:
# crystal config
generators:
readme:
version: latest
Then update your crystal project:
# example
cd $PROJECT_PATH
crystal update
This is the quick way to add a generator to your project and use it.
If you'd like to load a generator manually, you can do so by running:
# usage
crystal install <generator>
# example
crystal install readme
This will install the generator to your crystal home directory (set as ~/.crystal
by default).
This is useful for checking out the source code for a generator before using it.
Creating Generators puts you in control of code generation.
Generators use Handlebars syntax and are processed through a series of code templates & configurations to produce source code.
Whether you wish to create a completely unique generator or fine-tune an existing generator, creating generators allows you full control of the code that is produced.
Below is an example crystal.cson
file for the Django framework which defines python
as a language, model
as a pattern and the mapping for various types of details.
Since this example does not include the iterator
option, each model is compiled into a single file named models.py
.
languages:
- python
gen:
file:
dest: models.py
models:
mapping:
model:
details:
type:
bool: BooleanField
date: DateField
decimal: DecimalField
image: ImageField
model: ForeignKey
number: IntegerField
string: CharField
time: DateTimeField
Below is an example crystal.cson
file for the Doctrine framework which defines php
as a language, model
as a pattern and does not include mapping of detail types, since Doctrine doesn't use these.
Since Doctrine defines each model in a separate file, the files
object is used to place each file in the model/
directory.
files:
model:
data: models
dest: "models/{{name.pascal}}.php"
languages:
- php
patterns:
- model
gen/
.  This same logic can be applied to any other type of Generator including API Generators, Database Generators, Model Generators and more.
# {{@name}} {{@version}}
by<EMAIL_ADDRESS><EMAIL_ADDRESS>## Models
{{#each models}}
### {{name}}
#### Properties

Name
Type
Required
Unique

{{#each details}}

{{name}}
{{type}}
{{#if detail.required}}x{{/if}}
{{#if detail.unique}}x{{/if}}

{{/each}}

{{/each}}
To test this example:
gen
and add a file named README.md
.


Medinova is a library for Health & Medical with predefined web elements which helps you to build your own site.
These template is suitable for dental, doctor, care, clinic, corporate, dentist, health, pharmacy, health care, hospital, medical, medicine, fitness, professional, surgeon website.
Medinova template has a fully responsive layout. It fits perfectly on various displays and resolutions from regular desktop screens to tablets, iPads, iPhones and small mobile devices.
This template is built with both Bootstrap 4 & 3.
Note: All images are used for preview purpose only and not included in the final purchase files.
- Added: Bootstrap 4 Support! - Added: around 130 Home variations in Bootstrap 4. - Added: Converted all shortcodes and features pages to Bootstrap 4 support.
- Modified: Custom.js and jquery-plugin-collection.js - Modified: Shortcodes - Added: Gallery pages - Modified: google-map-init.js file - Added: google-map-init-multilocation.js file - Added: Google Map with Multi Marker Locations (page-contact5-with-multiple-marker.html) and (page-contact6-with-multiple-marker.html).
- Fixed: Some JS codes.
- Added: Hot layouts. - Added: Revolution slider examples. - Added: Doctors Timetable - Fixed: Some shortcodes. - Fixed: Some JS codes.
- Added: 5 new home variations. - Added: Boxed, vertical and mobile nav layouts. - Added: Portfolio Isotope Gallery. - Added: Dark and RTL layouts. - Added: Different Active Forms. - Added: Paypal Donate Forms. - Added: "Layer Slider" and "Master Slider" premium plugins.
- Added: 5 new Multipage Layouts. - Added: 5 new SinglePage Layouts. - Added: 10 Boxed Layouts. - Added: icons in client downloaded file
Initial release


This library provide the necessary mechanism to bootstrap a Zest™ Application in a Servlet container plus some facilities.
The SLF4J logger used by this library is named "org.apache.zest.library.servlet".
Extends {@link org.apache.zest.library.servlet.lifecycle.AbstractZestServletBootstrap} to easily bind a Zest™ {@link org.apache.zest.api.structure.Application} activation/passivation to your webapp lifecycle.
Use {@link org.apache.zest.library.servlet.ZestServletSupport#application(javax.servlet.ServletContext)} to get a handle on the {@link org.apache.zest.api.structure.Application} from the {@link javax.servlet.ServletContext}.
{@link org.apache.zest.library.servlet.ZestServlet} and {@link org.apache.zest.library.servlet.ZestFilter} respectively provide base class for easy access to the {@link org.apache.zest.api.structure.Application}} from the {@link javax.servlet.ServletContext}.


public interface DbQueryResult<CHAINTYPE extends DbQueryResult<?>>
| Modifier and Type | Method and Description |
|---|---|
<T> T |
build(int skip,
int count,
CollectionSearchQuery.CollectionEntryProcessor<T> processor)
Build a result out of the collection entries
|
default List<CollectionEntry> |
collectEntries()
Collect all
CollectionEntry objects as list |
List<CollectionEntry> |
collectEntries(int skip,
int count)
Collect all
CollectionEntry objects as list |
void |
collectEntries(int skip,
int count,
Collection<CollectionEntry> collection)
Collect all
CollectionEntry objects in a Collection |
Set<Integer> |
collectIds(int skip,
int count)
Return the note ids of the search result as an ordered
Set . |
void |
collectIds(int skip,
int count,
Collection<Integer> idTable)
Adds all note ids of the search result to a note ID collection, with special support
for
IDTable s |
CHAINTYPE |
computeValues(Map<String,String> itemsAndFormulas)
Dynamically computes virtual item values from the summary buffer data
|
CHAINTYPE |
computeValues(String... itemsAndFormulas)
Dynamically computes virtual item values from the summary buffer data
|
void |
forEachDocument(int skip,
int count,
BiConsumer<Document,Loop> consumer)
Iterates over each document in the search result
|
Stream<Document> |
getDocuments() |
Optional<IDTable> |
getNoteIds()
Returns an
IDTable of documents matching the search. |
Database |
getParentDatabase()
Returns the
Database that was used to run the query |
int |
size()
Returns the total number of results
|
CHAINTYPE |
sort(DominoCollection collection)
Sorts/filters the note ids of the search result like the specified
DominoCollection . |
Database getParentDatabase()
Database
that was used to run the queryOptional<IDTable> getNoteIds()
IDTable
of documents matching the search.Optional
describing the documents matched by the search, or
an empty one if the search did not request a document collection<T> T build(int skip, int count, CollectionSearchQuery.CollectionEntryProcessor<T> processor)
T
- result typeskip
- paging offsetcount
- paging countprocessor
- builder code to produce the resultSet<Integer> collectIds(int skip, int count)
Set
.
Implementations are likely, but not guaranteed, to return a LinkedHashSet
.
skip
- paging offsetcount
- paging countvoid collectIds(int skip, int count, Collection<Integer> idTable)
IDTable
sskip
- paging offsetcount
- paging countidTable
- note ID collectionCHAINTYPE computeValues(String... itemsAndFormulas)
itemsAndFormulas
- tuples with item name/formula; leave formula empty to read an existing document item, e.g. ["_created", "@Created", "Form", ""]CHAINTYPE computeValues(Map<String,String> itemsAndFormulas)
itemsAndFormulas
- map of item/formula pairsCHAINTYPE sort(DominoCollection collection)
DominoCollection
.
Note ids that are not part of the collection will be ignored.collection
- collectiondefault List<CollectionEntry> collectEntries()
CollectionEntry
objects as listList<CollectionEntry> collectEntries(int skip, int count)
CollectionEntry
objects as listskip
- paging offsetcount
- paging countvoid collectEntries(int skip, int count, Collection<CollectionEntry> collection)
CollectionEntry
objects in a Collection
skip
- paging offsetcount
- paging countcollection
- collection to add entriesvoid forEachDocument(int skip, int count, BiConsumer<Document,Loop> consumer)
skip
- paging offsetcount
- paging countconsumer
- consumer to receive documentint size()
Copyright © 2019–2021 HCL. All rights reserved.


Log in
Subscribe Today
Customer Service
P-Edition
Advertise
Top Workplaces
UnidosSC.com
Home
News
Sports
Entertainment
Business
Life
Opinion
Blogs
Photos
Obits
Register Connect
CARS
JOBS
HOMES
Shop
Classifieds
404 Not Found
The content you are looking for is unavailable.
Please use the search box at the top of this page to find the information you were seeking.
Click here to return to the home page.
ADVERTISEMENT
ADVERTISEMENT
Powered by the Parse.ly Publisher Platform (P3).


github
examples
docs
Predictable state management for ember apps
In this video, learn how to
build a reddit clone with ember-redux
,
redux-thunk
, and
reselect
.


Feb 22, 2017
Topics Discussed
- Cond
- If
- Predicates and Clauses
Question: What’s the explanation for Exercise 1.6 in SICP?
http://www.scipy-lectures.org/
Reference Material and random stuff
- Meaningful Modeling: What Is The Semantics of “Semantics”?, (Slides), (Harel, Rumpe 2004)
- MM: WITSoS? (Article)
- Traveling Salesman Problem
- Assembly 80x86 OpCodes
- “erik demaine p and np problems” on YouTube
- Base32 Encoding (Crockford)
- SICP on Archive.org


Your Email: Name: Colors Primary Color Second Color Tertiary(light) Color Tile type Metallic White $35 Hex multicolor = $99 Circuit = $60 Mother board = $120 Solar panel style = $89 Star Wars style = $79 iron = $49 mosaic = $139 graded = $109 non grated = $85 castle style = $99 Sheet Metal = $115 Special Floor = $399 tile special options Lights(extra $100) Epoxy(extra $50) Shine(extra $20) Super Polish(extra $48)


PERLPERF
Section: Perl Programmers Reference Guide (1)Updated: 2009-05-14
Index Return to Main Contents
NAME
perlperf - Perl Performance and Optimization TechniquesDESCRIPTION
This is an introduction to the use of performance and optimization techniques which can be used with particular reference to perl programs. While many perl developers have come from other languages, and can use their prior knowledge where appropriate, there are many other people who might benefit from a few perl specific pointers. If you want the condensed version, perhaps the best advice comes from the renowned Japanese Samurai, Miyamoto Musashi, who said:
"Do Not Engage in Useless Activity"
OVERVIEW
Perhaps the most common mistake programmers make is to attempt to optimize their code before a program actually does anything useful - this is a bad idea. There's no point in having an extremely fast program that doesn't work. The first job is to get a program to correctly do something useful, (not to mention ensuring the test suite is fully functional), and only then to consider optimizing it. Having decided to optimize existing working code, there are several simple but essential steps to consider which are intrinsic to any optimization process.ONE STEP SIDEWAYS
Firstly, you need to establish a baseline time for the existing code, which timing needs to be reliable and repeatable. You'll probably want to use the "Benchmark" or "Devel::DProf" modules, or something similar, for this step, or perhaps the unix system "time" utility, whichever is appropriate. See the base of this document for a longer list of benchmarking and profiling modules, and recommended further reading.ONE STEP FORWARD
Next, having examined the program for hot spots, (places where the code seems to run slowly), change the code with the intention of making it run faster. Using version control software, like "subversion", will ensure no changes are irreversible. It's too easy to fiddle here and fiddle there - don't change too much at any one time or you might not discover which piece of code really was the slow bit.ANOTHER STEP SIDEWAYS
It's not enough to say: ``that will make it run faster'', you have to check it. Rerun the code under control of the benchmarking or profiling modules, from the first step above, and check that the new code executed the same task in less time. Save your work and repeat...GENERAL GUIDELINES
The critical thing when considering performance is to remember there is no such thing as a "Golden Bullet", which is why there are no rules, only guidelines.It is clear that inline code is going to be faster than subroutine or method calls, because there is less overhead, but this approach has the disadvantage of being less maintainable and comes at the cost of greater memory usage - there is no such thing as a free lunch. If you are searching for an element in a list, it can be more efficient to store the data in a hash structure, and then simply look to see whether the key is defined, rather than to loop through the entire array using grep() for instance. substr() may be (a lot) faster than grep() but not as flexible, so you have another trade-off to access. Your code may contain a line which takes 0.01 of a second to execute which if you call it 1,000 times, quite likely in a program parsing even medium sized files for instance, you already have a 10 second delay, in just one single code location, and if you call that line 100,000 times, your entire program will slow down to an unbearable crawl.
Using a subroutine as part of your sort is a powerful way to get exactly what you want, but will usually be slower than the built-in alphabetic "cmp" and numeric "<=>" sort operators. It is possible to make multiple passes over your data, building indices to make the upcoming sort more efficient, and to use what is known as the "OM" (Orcish Maneuver) to cache the sort keys in advance. The cache lookup, while a good idea, can itself be a source of slowdown by enforcing a double pass over the data - once to setup the cache, and once to sort the data. Using "pack()" to extract the required sort key into a consistent string can be an efficient way to build a single string to compare, instead of using multiple sort keys, which makes it possible to use the standard, written in "c" and fast, perl "sort()" function on the output, and is the basis of the "GRT" (Guttman Rossler Transform). Some string combinations can slow the "GRT" down, by just being too plain complex for it's own good.
For applications using database backends, the standard "DBIx" namespace has tries to help with keeping things nippy, not least because it tries to not query the database until the latest possible moment, but always read the docs which come with your choice of libraries. Among the many issues facing developers dealing with databases should remain aware of is to always use "SQL" placeholders and to consider pre-fetching data sets when this might prove advantageous. Splitting up a large file by assigning multiple processes to parsing a single file, using say "POE", "threads" or "fork" can also be a useful way of optimizing your usage of the available "CPU" resources, though this technique is fraught with concurrency issues and demands high attention to detail.
Every case has a specific application and one or more exceptions, and there is no replacement for running a few tests and finding out which method works best for your particular environment, this is why writing optimal code is not an exact science, and why we love using Perl so much - TMTOWTDI.
BENCHMARKS
Here are a few examples to demonstrate usage of Perl's benchmarking tools.Assigning and Dereferencing Variables.
I'm sure most of us have seen code which looks like, (or worse than), this:
if ( $obj->{_ref}->{_myscore} >= $obj->{_ref}->{_yourscore} ) { ...
This sort of code can be a real eyesore to read, as well as being very sensitive to typos, and it's much clearer to dereference the variable explicitly. We're side-stepping the issue of working with object-oriented programming techniques to encapsulate variable access via methods, only accessible through an object. Here we're just discussing the technical implementation of choice, and whether this has an effect on performance. We can see whether this dereferencing operation, has any overhead by putting comparative code in a file and running a "Benchmark" test.
# dereference
#!/usr/bin/perl use strict; use warnings; use Benchmark; my $ref = { 'ref' => { _myscore => '100 + 1', _yourscore => '102 - 1', }, }; timethese(1000000, { 'direct' => sub { my $x = $ref->{ref}->{_myscore} . $ref->{ref}->{_yourscore} ; }, 'dereference' => sub { my $ref = $ref->{ref}; my $myscore = $ref->{_myscore}; my $yourscore = $ref->{_yourscore}; my $x = $myscore . $yourscore; }, });
It's essential to run any timing measurements a sufficient number of times so the numbers settle on a numerical average, otherwise each run will naturally fluctuate due to variations in the environment, to reduce the effect of contention for "CPU" resources and network bandwidth for instance. Running the above code for one million iterations, we can take a look at the report output by the "Benchmark" module, to see which approach is the most effective.
$> perl dereference Benchmark: timing 1000000 iterations of dereference, direct... dereference: 2 wallclock secs ( 1.59 usr + 0.00 sys = 1.59 CPU) @ 628930.82/s (n=1000000) direct: 1 wallclock secs ( 1.20 usr + 0.00 sys = 1.20 CPU) @ 833333.33/s (n=1000000)
The difference is clear to see and the dereferencing approach is slower. While it managed to execute an average of 628,930 times a second during our test, the direct approach managed to run an additional 204,403 times, unfortunately. Unfortunately, because there are many examples of code written using the multiple layer direct variable access, and it's usually horrible. It is, however, miniscully faster. The question remains whether the minute gain is actually worth the eyestrain, or the loss of maintainability.
Search and replace or tr
If we have a string which needs to be modified, while a regex will almost always be much more flexible, "tr", an oft underused tool, can still be a useful. One scenario might be replace all vowels with another character. The regex solution might look like this:
$str =~ s/[aeiou]/x/g
The "tr" alternative might look like this:
$str =~ tr/aeiou/xxxxx/
We can put that into a test file which we can run to check which approach is the fastest, using a global $STR variable to assign to the "my $str" variable so as to avoid perl trying to optimize any of the work away by noticing it's assigned only the once.
# regex-transliterate
#!/usr/bin/perl use strict; use warnings; use Benchmark; my $STR = "$$-this and that"; timethese( 1000000, { 'sr' => sub { my $str = $STR; $str =~ s/[aeiou]/x/g; return $str; }, 'tr' => sub { my $str = $STR; $str =~ tr/aeiou/xxxxx/; return $str; }, });
Running the code gives us our results:
$> perl regex-transliterate Benchmark: timing 1000000 iterations of sr, tr... sr: 2 wallclock secs ( 1.19 usr + 0.00 sys = 1.19 CPU) @ 840336.13/s (n=1000000) tr: 0 wallclock secs ( 0.49 usr + 0.00 sys = 0.49 CPU) @ 2040816.33/s (n=1000000)
The "tr" version is a clear winner. One solution is flexible, the other is fast - and it's appropriately the programmers choice which to use in the circumstances.
Check the "Benchmark" docs for further useful techniques.
PROFILING TOOLS
A slightly larger piece of code will provide something on which a profiler can produce more extensive reporting statistics. This example uses the simplistic "wordmatch" program which parses a given input file and spews out a short report on the contents.# wordmatch
#!/usr/bin/perl use strict; use warnings; =head1 NAME filewords - word analysis of input file =head1 SYNOPSIS filewords -f inputfilename [-d] =head1 DESCRIPTION This program parses the given filename, specified with C<-f>, and displays a simple analysis of the words found therein. Use the C<-d> switch to enable debugging messages. =cut use FileHandle; use Getopt::Long; my $debug = 0; my $file = ''; my $result = GetOptions ( 'debug' => \$debug, 'file=s' => \$file, ); die("invalid args") unless $result; unless ( -f $file ) { die("Usage: $0 -f filename [-d]"); } my $FH = FileHandle->new("< $file") or die("unable to open file($file): $!"); my $i_LINES = 0; my $i_WORDS = 0; my %count = (); my @lines = <$FH>; foreach my $line ( @lines ) { $i_LINES++; $line =~ s/\n//; my @words = split(/ +/, $line); my $i_words = scalar(@words); $i_WORDS = $i_WORDS + $i_words; debug("line: $i_LINES supplying $i_words words: @words"); my $i_word = 0; foreach my $word ( @words ) { $i_word++; $count{$i_LINES}{spec} += matches($i_word, $word, '[^a-zA-Z0-9]'); $count{$i_LINES}{only} += matches($i_word, $word, '^[^a-zA-Z0-9]+$'); $count{$i_LINES}{cons} += matches($i_word, $word, '^[(?i:bcdfghjklmnpqrstvwxyz)]+$'); $count{$i_LINES}{vows} += matches($i_word, $word, '^[(?i:aeiou)]+$'); $count{$i_LINES}{caps} += matches($i_word, $word, '^[(A-Z)]+$'); } } print report( %count ); sub matches { my $i_wd = shift; my $word = shift; my $regex = shift; my $has = 0; if ( $word =~ /($regex)/ ) { $has++ if $1; } debug("word: $i_wd ".($has ? 'matches' : 'does not match')." chars: /$regex/"); return $has; } sub report { my %report = @_; my %rep; foreach my $line ( keys %report ) { foreach my $key ( keys %{ $report{$line} } ) { $rep{$key} += $report{$line}{$key}; } } my $report = qq| $0 report for $file: lines in file: $i_LINES words in file: $i_WORDS words with special (non-word) characters: $i_spec words with only special (non-word) characters: $i_only words with only consonants: $i_cons words with only capital letters: $i_caps words with only vowels: $i_vows |; return $report; } sub debug { my $message = shift; if ( $debug ) { print STDERR "DBG: $message\n"; } } exit 0;
Devel::DProf
This venerable module has been the de-facto standard for Perl code profiling for more than a decade, but has been replaced by a number of other modules which have brought us back to the 21st century. Although you're recommended to evaluate your tool from the several mentioned here and from the CPAN list at the base of this document, (and currently Devel::NYTProf seems to be the weapon of choice - see below), we'll take a quick look at the output from Devel::DProf first, to set a baseline for Perl profiling tools. Run the above program under the control of "Devel::DProf" by using the "-d" switch on the command-line.
$> perl -d:DProf wordmatch -f perl5db.pl <...multiple lines snipped...> wordmatch report for perl5db.pl: lines in file: 9428 words in file: 50243 words with special (non-word) characters: 20480 words with only special (non-word) characters: 7790 words with only consonants: 4801 words with only capital letters: 1316 words with only vowels: 1701
"Devel::DProf" produces a special file, called tmon.out by default, and this file is read by the "dprofpp" program, which is already installed as part of the "Devel::DProf" distribution. If you call "dprofpp" with no options, it will read the tmon.out file in the current directory and produce a human readable statistics report of the run of your program. Note that this may take a little time.
$> dprofpp Total Elapsed Time = 2.951677 Seconds User+System Time = 2.871677 Seconds Exclusive Times %Time ExclSec CumulS #Calls sec/call Csec/c Name 102. 2.945 3.003 251215 0.0000 0.0000 main::matches 2.40 0.069 0.069 260643 0.0000 0.0000 main::debug 1.74 0.050 0.050 1 0.0500 0.0500 main::report 1.04 0.030 0.049 4 0.0075 0.0123 main::BEGIN 0.35 0.010 0.010 3 0.0033 0.0033 Exporter::as_heavy 0.35 0.010 0.010 7 0.0014 0.0014 IO::File::BEGIN 0.00 - -0.000 1 - - Getopt::Long::FindOption 0.00 - -0.000 1 - - Symbol::BEGIN 0.00 - -0.000 1 - - Fcntl::BEGIN 0.00 - -0.000 1 - - Fcntl::bootstrap 0.00 - -0.000 1 - - warnings::BEGIN 0.00 - -0.000 1 - - IO::bootstrap 0.00 - -0.000 1 - - Getopt::Long::ConfigDefaults 0.00 - -0.000 1 - - Getopt::Long::Configure 0.00 - -0.000 1 - - Symbol::gensym
"dprofpp" will produce some quite detailed reporting on the activity of the "wordmatch" program. The wallclock, user and system, times are at the top of the analysis, and after this are the main columns defining which define the report. Check the "dprofpp" docs for details of the many options it supports.
See also "Apache::DProf" which hooks "Devel::DProf" into "mod_perl".
Devel::Profiler
Let's take a look at the same program using a different profiler: "Devel::Profiler", a drop-in Perl-only replacement for "Devel::DProf". The usage is very slightly different in that instead of using the special "-d:" flag, you pull "Devel::Profiler" in directly as a module using "-M".
$> perl -MDevel::Profiler wordmatch -f perl5db.pl <...multiple lines snipped...> wordmatch report for perl5db.pl: lines in file: 9428 words in file: 50243 words with special (non-word) characters: 20480 words with only special (non-word) characters: 7790 words with only consonants: 4801 words with only capital letters: 1316 words with only vowels: 1701
"Devel::Profiler" generates a tmon.out file which is compatible with the "dprofpp" program, thus saving the construction of a dedicated statistics reader program. "dprofpp" usage is therefore identical to the above example.
$> dprofpp Total Elapsed Time = 20.984 Seconds User+System Time = 19.981 Seconds Exclusive Times %Time ExclSec CumulS #Calls sec/call Csec/c Name 49.0 9.792 14.509 251215 0.0000 0.0001 main::matches 24.4 4.887 4.887 260643 0.0000 0.0000 main::debug 0.25 0.049 0.049 1 0.0490 0.0490 main::report 0.00 0.000 0.000 1 0.0000 0.0000 Getopt::Long::GetOptions 0.00 0.000 0.000 2 0.0000 0.0000 Getopt::Long::ParseOptionSpec 0.00 0.000 0.000 1 0.0000 0.0000 Getopt::Long::FindOption 0.00 0.000 0.000 1 0.0000 0.0000 IO::File::new 0.00 0.000 0.000 1 0.0000 0.0000 IO::Handle::new 0.00 0.000 0.000 1 0.0000 0.0000 Symbol::gensym 0.00 0.000 0.000 1 0.0000 0.0000 IO::File::open
Interestingly we get slightly different results, which is mostly because the algorithm which generates the report is different, even though the output file format was allegedly identical. The elapsed, user and system times are clearly showing the time it took for "Devel::Profiler" to execute it's own run, but the column listings feel more accurate somehow than the ones we had earlier from "Devel::DProf". The 102% figure has disappeared, for example. This is where we have to use the tools at our disposal, and recognise their pros and cons, before using them. Interestingly, the numbers of calls for each subroutine are identical in the two reports, it's the percentages which differ. As the author of "Devel::Proviler" writes:
...running HTML::Template's test suite under Devel::DProf shows output() taking NO time but Devel::Profiler shows around 10% of the time is in output(). I don't know which to trust but my gut tells me something is wrong with Devel::DProf. HTML::Template::output() is a big routine that's called for every test. Either way, something needs fixing.
YMMV.
See also "Devel::Apache::Profiler" which hooks "Devel::Profiler" into "mod_perl".
Devel::SmallProf
The "Devel::SmallProf" profiler examines the runtime of your Perl program and produces a line-by-line listing to show how many times each line was called, and how long each line took to execute. It is called by supplying the familiar "-d" flag to Perl at runtime.
$> perl -d:SmallProf wordmatch -f perl5db.pl <...multiple lines snipped...> wordmatch report for perl5db.pl: lines in file: 9428 words in file: 50243 words with special (non-word) characters: 20480 words with only special (non-word) characters: 7790 words with only consonants: 4801 words with only capital letters: 1316 words with only vowels: 1701
"Devel::SmallProf" writes it's output into a file called smallprof.out, by default. The format of the file looks like this:
<num> <time> <ctime> <line>:<text>
When the program has terminated, the output may be examined and sorted using any standard text filtering utilities. Something like the following may be sufficient:
$> cat smallprof.out | grep \d*: | sort -k3 | tac | head -n20 251215 1.65674 7.68000 75: if ( $word =~ /($regex)/ ) { 251215 0.03264 4.40000 79: debug("word: $i_wd ".($has ? 'matches' : 251215 0.02693 4.10000 81: return $has; 260643 0.02841 4.07000 128: if ( $debug ) { 260643 0.02601 4.04000 126: my $message = shift; 251215 0.02641 3.91000 73: my $has = 0; 251215 0.03311 3.71000 70: my $i_wd = shift; 251215 0.02699 3.69000 72: my $regex = shift; 251215 0.02766 3.68000 71: my $word = shift; 50243 0.59726 1.00000 59: $count{$i_LINES}{cons} = 50243 0.48175 0.92000 61: $count{$i_LINES}{spec} = 50243 0.00644 0.89000 56: my $i_cons = matches($i_word, $word, 50243 0.48837 0.88000 63: $count{$i_LINES}{caps} = 50243 0.00516 0.88000 58: my $i_caps = matches($i_word, $word, '^[(A- 50243 0.00631 0.81000 54: my $i_spec = matches($i_word, $word, '[^a- 50243 0.00496 0.80000 57: my $i_vows = matches($i_word, $word, 50243 0.00688 0.80000 53: $i_word++; 50243 0.48469 0.79000 62: $count{$i_LINES}{only} = 50243 0.48928 0.77000 60: $count{$i_LINES}{vows} = 50243 0.00683 0.75000 55: my $i_only = matches($i_word, $word, '^[^a-
You can immediately see a slightly different focus to the subroutine profiling modules, and we start to see exactly which line of code is taking the most time. That regex line is looking a bit suspicious, for example. Remember that these tools are supposed to be used together, there is no single best way to profile your code, you need to use the best tools for the job.
See also "Apache::SmallProf" which hooks "Devel::SmallProf" into "mod_perl".
Devel::FastProf
"Devel::FastProf" is another Perl line profiler. This was written with a view to getting a faster line profiler, than is possible with for example "Devel::SmallProf", because it's written in "C". To use "Devel::FastProf", supply the "-d" argument to Perl:
$> perl -d:FastProf wordmatch -f perl5db.pl <...multiple lines snipped...> wordmatch report for perl5db.pl: lines in file: 9428 words in file: 50243 words with special (non-word) characters: 20480 words with only special (non-word) characters: 7790 words with only consonants: 4801 words with only capital letters: 1316 words with only vowels: 1701
"Devel::FastProf" writes statistics to the file fastprof.out in the current directory. The output file, which can be specified, can be interpreted by using the "fprofpp" command-line program.
$> fprofpp | head -n20 # fprofpp output format is: # filename:line time count: source wordmatch:75 3.93338 251215: if ( $word =~ /($regex)/ ) { wordmatch:79 1.77774 251215: debug("word: $i_wd ".($has ? 'matches' : 'does not match')." chars: /$regex/"); wordmatch:81 1.47604 251215: return $has; wordmatch:126 1.43441 260643: my $message = shift; wordmatch:128 1.42156 260643: if ( $debug ) { wordmatch:70 1.36824 251215: my $i_wd = shift; wordmatch:71 1.36739 251215: my $word = shift; wordmatch:72 1.35939 251215: my $regex = shift;
Straightaway we can see that the number of times each line has been called is identical to the "Devel::SmallProf" output, and the sequence is only very slightly different based on the ordering of the amount of time each line took to execute, "if ( $debug ) { " and "my $message = shift;", for example. The differences in the actual times recorded might be in the algorithm used internally, or it could be due to system resource limitations or contention.
See also the DBIx::Profiler which will profile database queries running under the "DBIx::*" namespace.
Devel::NYTProf
"Devel::NYTProf" is the next generation of Perl code profiler, fixing many shortcomings in other tools and implementing many cool features. First of all it can be used as either a line profiler, a block or a subroutine profiler, all at once. It can also use sub-microsecond (100ns) resolution on systems which provide "clock_gettime()". It can be started and stopped even by the program being profiled. It's a one-line entry to profile "mod_perl" applications. It's written in "c" and is probably the fastest profiler available for Perl. The list of coolness just goes on. Enough of that, let's see how to it works - just use the familiar "-d" switch to plug it in and run the code.
$> perl -d:NYTProf wordmatch -f perl5db.pl wordmatch report for perl5db.pl: lines in file: 9427 words in file: 50243 words with special (non-word) characters: 20480 words with only special (non-word) characters: 7790 words with only consonants: 4801 words with only capital letters: 1316 words with only vowels: 1701
"NYTProf" will generate a report database into the file nytprof.out by default. Human readable reports can be generated from here by using the supplied "nytprofhtml" (HTML output) and "nytprofcsv" (CSV output) programs. We've used the unix sytem "html2text" utility to convert the nytprof/index.html file for convenience here.
$> html2text nytprof/index.html Performance Profile Index For wordmatch Run on Fri Sep 26 13:46:39 2008 Reported on Fri Sep 26 13:47:23 2008 Top 15 Subroutines -- ordered by exclusive time |Calls |P |F |Inclusive|Exclusive|Subroutine | | | | |Time |Time | | |251215|5 |1 |13.09263 |10.47692 |main:: |matches | |260642|2 |1 |2.71199 |2.71199 |main:: |debug | |1 |1 |1 |0.21404 |0.21404 |main:: |report | |2 |2 |2 |0.00511 |0.00511 |XSLoader:: |load (xsub) | |14 |14|7 |0.00304 |0.00298 |Exporter:: |import | |3 |1 |1 |0.00265 |0.00254 |Exporter:: |as_heavy | |10 |10|4 |0.00140 |0.00140 |vars:: |import | |13 |13|1 |0.00129 |0.00109 |constant:: |import | |1 |1 |1 |0.00360 |0.00096 |FileHandle:: |import | |3 |3 |3 |0.00086 |0.00074 |warnings::register::|import | |9 |3 |1 |0.00036 |0.00036 |strict:: |bits | |13 |13|13|0.00032 |0.00029 |strict:: |import | |2 |2 |2 |0.00020 |0.00020 |warnings:: |import | |2 |1 |1 |0.00020 |0.00020 |Getopt::Long:: |ParseOptionSpec| |7 |7 |6 |0.00043 |0.00020 |strict:: |unimport | For more information see the full list of 189 subroutines.
The first part of the report already shows the critical information regarding which subroutines are using the most time. The next gives some statistics about the source files profiled.
Source Code Files -- ordered by exclusive time then name |Stmts |Exclusive|Avg. |Reports |Source File | | |Time | | | | |2699761|15.66654 |6e-06 |line . block . sub|wordmatch | |35 |0.02187 |0.00062|line . block . sub|IO/Handle.pm | |274 |0.01525 |0.00006|line . block . sub|Getopt/Long.pm | |20 |0.00585 |0.00029|line . block . sub|Fcntl.pm | |128 |0.00340 |0.00003|line . block . sub|Exporter/Heavy.pm | |42 |0.00332 |0.00008|line . block . sub|IO/File.pm | |261 |0.00308 |0.00001|line . block . sub|Exporter.pm | |323 |0.00248 |8e-06 |line . block . sub|constant.pm | |12 |0.00246 |0.00021|line . block . sub|File/Spec/Unix.pm | |191 |0.00240 |0.00001|line . block . sub|vars.pm | |77 |0.00201 |0.00003|line . block . sub|FileHandle.pm | |12 |0.00198 |0.00016|line . block . sub|Carp.pm | |14 |0.00175 |0.00013|line . block . sub|Symbol.pm | |15 |0.00130 |0.00009|line . block . sub|IO.pm | |22 |0.00120 |0.00005|line . block . sub|IO/Seekable.pm | |198 |0.00085 |4e-06 |line . block . sub|warnings/register.pm| |114 |0.00080 |7e-06 |line . block . sub|strict.pm | |47 |0.00068 |0.00001|line . block . sub|warnings.pm | |27 |0.00054 |0.00002|line . block . sub|overload.pm | |9 |0.00047 |0.00005|line . block . sub|SelectSaver.pm | |13 |0.00045 |0.00003|line . block . sub|File/Spec.pm | |2701595|15.73869 | |Total | |128647 |0.74946 | |Average | | |0.00201 |0.00003|Median | | |0.00121 |0.00003|Deviation | Report produced by the NYTProf 2.03 Perl profiler, developed by Tim Bunce and Adam Kaplan.
At this point, if you're using the html report, you can click through the various links to bore down into each subroutine and each line of code.
See also "Devel::NYTProf::Apache" which hooks "Devel::NYTProf" into "mod_perl".
SORTING
Perl modules are not the only tools a performance analyst has at their disposal, system tools like "time" should not be overlooked as the next example shows, where we take a quick look at sorting. Many books, theses and articles, have been written about efficient sorting algorithms, and this is not the place to repeat such work, there's several good sorting modules which deserve taking a look at too: "Sort::Maker", "Sort::Key" spring to mind. However, it's still possible to make some observations on certain Perl specific interpretations on issues relating to sorting data sets and give an example or two with regard to how sorting large data volumes can effect performance. Firstly, an often overlooked point when sorting large amounts of data, one can attempt to reduce the data set to be dealt with and in many cases "grep()" can be quite useful as a simple filter:
@data = sort grep { /$filter/ } @incoming
A command such as this can vastly reduce the volume of material to actually sort through in the first place, and should not be too lightly disregarded purely on the basis of it's simplicity. The "KISS" principle is too often overlooked - the next example uses the simple system "time" utility to demonstrate. Let's take a look at an actual example of sorting the contents of a large file, an apache logfile would do.  One solution might be to use the following code, which iterates over the files given on the command-line.
# sort-apache-log
#!/usr/bin/perl -n use strict; use warnings; my @data; LINE: while ( <> ) { my $line = $_; if ( $line =~ m/^( ([\w\.\-]+) # client \s*-\s*-\s*\[ ([^]]+) # date \]\s*"\w+\s* (\S+) # query [^"]+"\s* (\d+) # status \s+\S+\s+"[^"]*"\s+" ([^"]*) # browser " .* )$/x ) { my @chunks = split(/ +/, $line); my $ip = $1; my $date = $2; my $query = $3; my $status = $4; my $browser = $5; push(@data, [$ip, $date, $query, $status, $browser, $line]); } } my @sorted = sort { $a->[3] cmp $b->[3] || $a->[2] cmp $b->[2] || $a->[0] cmp $b->[0] || $a->[1] cmp $b->[1] || $a->[4] cmp $b->[4] } @data; foreach my $data ( @sorted ) { print $data->[5]; } exit 0;
When running this program, redirect "STDOUT" so it is possible to check the output is correct from following test runs and use the system "time" utility to check the overall runtime.
$> time ./sort-apache-log logfile > out-sort real 0m17.371s user 0m15.757s sys 0m0.592s
The program took just over 17 wallclock seconds to run. Note the different values "time" outputs, it's important to always use the same one, and to not confuse what each one means.
- Elapsed Real Time
- The overall, or wallclock, time between when "time" was called, and when it terminates. The elapsed time includes both user and system times, and time spent waiting for other users and processes on the system. Inevitably, this is the most approximate of the measurements given.
- User CPU Time
- The user time is the amount of time the entire process spent on behalf of the user on this system executing this program.
- System CPU Time
- The system time is the amount of time the kernel itself spent executing routines, or system calls, on behalf of this process user.
Running this same process as a "Schwarzian Transform" it is possible to eliminate the input and output arrays for storing all the data, and work on the input directly as it arrives too. Otherwise, the code looks fairly similar:
# sort-apache-log-schwarzian
#!/usr/bin/perl -n use strict; use warnings; print map $_->[0] => sort { $a->[4] cmp $b->[4] || $a->[3] cmp $b->[3] || $a->[1] cmp $b->[1] || $a->[2] cmp $b->[2] || $a->[5] cmp $b->[5] } map [ $_, m/^( ([\w\.\-]+) # client \s*-\s*-\s*\[ ([^]]+) # date \]\s*"\w+\s* (\S+) # query [^"]+"\s* (\d+) # status \s+\S+\s+"[^"]*"\s+" ([^"]*) # browser " .* )$/xo ] => <>; exit 0;
Run the new code against the same logfile, as above, to check the new time.
$> time ./sort-apache-log-schwarzian logfile > out-schwarz real 0m9.664s user 0m8.873s sys 0m0.704s
The time has been cut in half, which is a respectable speed improvement by any standard. Naturally, it is important to check the output is consistent with the first program run, this is where the unix system "cksum" utility comes in.
$> cksum out-sort out-schwarz<PHONE_NUMBER> 52029194 out-sort<PHONE_NUMBER> 52029194 out-schwarz
BTW. Beware too of pressure from managers who see you speed a program up by 50% of the runtime once, only to get a request one month later to do the same again (true story) - you'll just have to point out your only human, even if you are a Perl programmer, and you'll see what you can do...
LOGGING
An essential part of any good development process is appropriate error handling with appropriately informative messages, however there exists a school of thought which suggests that log files should be chatty, as if the chain of unbroken output somehow ensures the survival of the program. If speed is in any way an issue, this approach is wrong.A common sight is code which looks something like this:
logger->debug( "A logging message via process-id: $$ INC: " . Dumper(\%INC) )
The problem is that this code will always be parsed and executed, even when the debug level set in the logging configuration file is zero. Once the debug() subroutine has been entered, and the internal $debug variable confirmed to be zero, for example, the message which has been sent in will be discarded and the program will continue. In the example given though, the \%INC hash will already have been dumped, and the message string constructed, all of which work could be bypassed by a debug variable at the statement level, like this:
logger->debug( "A logging message via process-id: $$ INC: " . Dumper(\%INC) ) if $DEBUG;
This effect can be demonstrated by setting up a test script with both forms, including a "debug()" subroutine to emulate typical "logger()" functionality.
# ifdebug
#!/usr/bin/perl use strict; use warnings; use Benchmark; use Data::Dumper; my $DEBUG = 0; sub debug { my $msg = shift; if ( $DEBUG ) { print "DEBUG: $msg\n"; } }; timethese(100000, { 'debug' => sub { debug( "A $0 logging message via process-id: $$" . Dumper(\%INC) ) }, 'ifdebug' => sub { debug( "A $0 logging message via process-id: $$" . Dumper(\%INC) ) if $DEBUG }, });
Let's see what "Benchmark" makes of this:
$> perl ifdebug Benchmark: timing 100000 iterations of constant, sub... ifdebug: 0 wallclock secs ( 0.01 usr + 0.00 sys = 0.01 CPU) @ 10000000.00/s (n=100000) (warning: too few iterations for a reliable count) debug: 14 wallclock secs (13.18 usr + 0.04 sys = 13.22 CPU) @ 7564.30/s (n=100000)
In the one case the code, which does exactly the same thing as far as outputting any debugging information is concerned, in other words nothing, takes 14 seconds, and in the other case the code takes one hundredth of a second. Looks fairly definitive. Use a $DEBUG variable BEFORE you call the subroutine, rather than relying on the smart functionality inside it.
Logging if DEBUG (constant)
It's possible to take the previous idea a little further, by using a compile time "DEBUG" constant.# ifdebug-constant
#!/usr/bin/perl use strict; use warnings; use Benchmark; use Data::Dumper; use constant DEBUG => 0 ; sub debug { if ( DEBUG ) { my $msg = shift; print "DEBUG: $msg\n"; } }; timethese(100000, { 'debug' => sub { debug( "A $0 logging message via process-id: $$" . Dumper(\%INC) ) }, 'constant' => sub { debug( "A $0 logging message via process-id: $$" . Dumper(\%INC) ) if DEBUG }, });
Running this program produces the following output:
$> perl ifdebug-constant Benchmark: timing 100000 iterations of constant, sub... constant: 0 wallclock secs (-0.00 usr + 0.00 sys = -0.00 CPU) @ -7205759403792793600000.00/s (n=100000) (warning: too few iterations for a reliable count) sub: 14 wallclock secs (13.09 usr + 0.00 sys = 13.09 CPU) @ 7639.42/s (n=100000)
The "DEBUG" constant wipes the floor with even the $debug variable, clocking in at minus zero seconds, and generates a ``warning: too few iterations for a reliable count'' message into the bargain. To see what is really going on, and why we had too few iterations when we thought we asked for 100000, we can use the very useful "B::Deparse" to inspect the new code:
$> perl -MO=Deparse ifdebug-constant use Benchmark; use Data::Dumper; use constant ('DEBUG', 0); sub debug { use warnings; use strict 'refs'; 0; } use warnings; use strict 'refs'; timethese(100000, {'sub', sub { debug "A $0 logging message via process-id: $$" . Dumper(\%INC); } , 'constant', sub { 0; } }); ifdebug-constant syntax OK
The output shows the constant() subroutine we're testing being replaced with the value of the "DEBUG" constant: zero. The line to be tested has been completely optimized away, and you can't get much more efficient than that.
POSTSCRIPT
This document has provided several way to go about identifying hot-spots, and checking whether any modifications have improved the runtime of the code.As a final thought, remember that it's not (at the time of writing) possible to produce a useful program which will run in zero or negative time and this basic principle can be written as: useful programs are slow by their very definition. It is of course possible to write a nearly instantaneous program, but it's not going to do very much, here's a very efficient one:
$> perl -e 0
Optimizing that any further is a job for "p5p".
SEE ALSO
Further reading can be found using the modules and links below.PERLDOCS
For example: "perldoc -f sort".perlfaq4.
perlfork, perlfunc, perlretut, perlthrtut.
MAN PAGES
"time".MODULES
It's not possible to individually showcase all the performance related code for Perl here, naturally, but here's a short list of modules from the CPAN which deserve further attention.
Apache::DProf Apache::SmallProf Benchmark DBIx::Profiler Devel::AutoProfiler Devel::DProf Devel::DProfLB Devel::FastProf Devel::GraphVizProf Devel::NYTProf Devel::NYTProf::Apache Devel::Profiler Devel::Profile Devel::Profit Devel::SmallProf Devel::WxProf POE::Devel::Profiler Sort::Key Sort::Maker
URLS
Very useful online reference material:
http://www.ccl4.org/~nick/P/Fast_Enough/ http://www-128.ibm.com/developerworks/library/l-optperl.html http://perlbuzz.com/2007/11/bind-output-variables-in-dbi-for-speed-and-safety.html http://en.wikipedia.org/wiki/Performance_analysis http://apache.perl.org/docs/1.0/guide/performance.html http://perlgolf.sourceforge.net/ http://www.sysarch.com/Perl/sort_paper.html http://www.unix.org.ua/orelly/perl/prog/ch08_03.htm
AUTHOR
Richard Foley<EMAIL_ADDRESS>Copyright (c) 2008
Index
- NAME
- DESCRIPTION
- OVERVIEW
- GENERAL GUIDELINES
- BENCHMARKS
- PROFILING TOOLS
- SORTING
- LOGGING
- POSTSCRIPT
- SEE ALSO
- AUTHOR
This document was created by man2html, using the manual pages.
Time: 05:29:08 GMT, December 24, 2015


Id: 291
Name: Rick J-22
Status: Alive
Species: Human
Type:
Gender: Male
OriginName: Earth (J-22)
OriginUrl: https://rickandmortyapi.com/api/location/62
LocationName: Citadel of Ricks
LocationUrl: https://rickandmortyapi.com/api/location/3
Image: https://rickandmortyapi.com/api/character/avatar/291.jpeg
Episode: ['https://rickandmortyapi.com/api/episode/28']
Url: https://rickandmortyapi.com/api/character/291
Created: 2017-12-31T20:16:52.337Z


Details
ATG Team: alyschu, Dnton, Craxuan, Rubble
Synopsis
Hunted for possessing a heaven-defying object, Yun Che is a young man in both that life and the next. Throwing himself off a cliff to spite his pursuers, Yun Che is reincarnated as Xiao Che, a recently poisoned teen in another realm. Just as hated in this life as the previous one, Che must overcome his own hostile clan, his own inability to cultivate, and his own frosty fiancée.


Aljun
Porfolio
About me
Contact
Cases
I AM FREELANCE
WEB DEVELOPER
With specialty in back-end development, functionality, UX design, and search engine optimization.
Cases
Portfolio
Aljun
About
Contact
Lorem


Look: Lil Nas X Shares Epic AMAs Moments W/ Megan Thee Stallion, Toni Braxton, Regina King + More
by Team SOHHRap rookie Lil Nas X is living his best life these days. The hip-hop star went online Monday to share a slew of slideshow pics from last night’s memorable American Music Awards show. Look and comment below!


This paragraph is in a shadow tree and can be reached because the part
attribute is set.
This paragraph is in a shadow tree and cannot be reached because the part
attribute is
not set.
This paragraph exists in a nested shadow tree and can be reached because its part
attribute is set
and exported.
This paragraph exists in a nested shadow tree but its part
attribute is not exported.


Recipes Catered to Your Kitchen
Saved Recipes
Compost Locations
What ingredients are we working with?
Dietary Restrictions
None
Vegan
Vegetarian
Gluten-Free
Dairy-Free
Let's Whip Something Up!


Baby Back Ribs
From: AllRecipes.com
Prep Time: 8 hr |
Cook Time: 2.5 hr |
Servings: 4 |
Ingredients:
- 2 pounds pork baby back ribs
- 1 (18 ounce) bottle barbecue sauce
Estimated Weight: 3.2 lb
Directions:
- Tear off 4 pieces of aluminum foil big enough to enclose each portion of ribs. Spray each piece of foil with vegetable cooking spray. Brush the ribs liberally with barbeque sauce and place each portion in its own piece of foil. Wrap tightly and refrigerate for at least 8 hours, or overnight.
- Preheat oven to 300 degrees F (150 degrees C)
- Bake ribs wrapped tightly in the foil for 2 1/2 hours. Remove from foil and add more sauce, if desired.


***Background***
I was only introduced to Salvia about 3 months ago. Since that moment, I've smoked it roughly 10 times (always being 50x). I am not a drug-user of any kind with the exception of Salvia. I had tried marijuana a few times. Those few times were my only previous encounters with smoking in any way.
***Method***
Being an avid swimmer, I have a large lung-capacity. I smoked a relatively large sized bowl of 50x extract Salvia out of an apple turned into a pipe using a hallowed pen tube. I only took one hit, but it was as much as my lungs could physically hold. I can hold my breathe just over 2 minutes. I did not have a sitter or company of any kind. It was my first solo experience. I only felt safe doing it alone because of the other 10 (roughly) times I've smoked Salvia, I've always remained 100% motionless and 100% silent. I pretty much just stare at a particular spot or have my eyes closed and remain completely immobile.
***Foreward***
I am very heavily into lucid dreaming. For this reason, each time I smoke Salvia my trips are always visually-based. I get very vivid pictures. I also tend to lose all senses in my current environment and in turn experience senses that my mind perceives to be there. I am also very open to many different interpretations of our universe, reality, etc. I enjoy studying different theories about these things, and hence there's is a lot of it in my subconscious mind. I think these subconcious ideas are what Salvia triggers in my brain most frequently.
***Experience***
I think I put too much Salvia in the bowl...so after I take a hit of as much as my lungs can handle, I look down at the remaining extract-leaves still burning (and being wasted) to which I think 'Man, that sucks.'  I see a very large cloud of smoke shoot out my mouth as I start flying out of my body at speeds I can only say are multiple times faster than lightspeed. In less than the blink of an eye I pass our atmosphere, the edges of our universe, and far past the fabrics of our very existence. I'm now hovering over an orb of what I perceive to be all of mankind's reality.
Unable to move, I realize that I'm hidden in a box with one of the edges being a bit torn open allowing in light. They're two children playing outside of this box and judging by their noises, shadows, and vibrations: they're very large. I'd put myself as the equivalent size of a small action figure witnessing their world. These two children, one boy and one girl, are presumably siblings. As they play, I become aware that I'm in their home's driveway. I suddenly hear their mother yelling to them from the minivan at the end of the driveway to hurry up. Her tone implied that they needed to get their belongings and go with her.
Both children rush towards my direction: the girl straight at me and the boy just passing my right. The brother screams to the sister 'Hurry! Put yours out!' after he notices me hovering above our orb of reality. His statement was said with fear and worry emoting from his voice as if to say 'Stop him from witnessing this!' or 'Don't allow mother to see what you've got!' I inferred the notion 'Put yours out!' to be slang in their world for taking care of an escaping mind from what I can only refer to as a 'reality-orb.' It is also inferred that the boy had an orb of another reality in his possession so that he could not be bothered with his younger sister's orb. The overall fear and panic I got from the siblings reactions was that they knew they were far too small and irresponsible to be in charge of such precious possessions and they knew if they were caught, they'd be in trouble.
I see the figure of a little girl getting closer and closer to me with an overall cluelessness about what it takes to be in charge of something so complex. She gently wraps her hands around me and pushes me back down to my orb as if to send my mind back to its body and hence, back to reality. I suddenly become slightly aware that I'm in my bedroom and I instantly want to go back. As she continues to push me down, she's not looking at me as if to make sure no one is coming, especially her mother, to see what it is she's in possession of. Because she isn't looking, I decide to push back between her fingers to observe their world for a bit longer. This temporarily works and I continue to watch the back of the small girls head a bit longer. It is then only a matter of moments before the girl notices I am trying to escape and she pushes me back down completely. It is at this very moment that I return to my body in my bedroom and the effects of the salvia quickly fade away.
***Aftermath***
With the exception of my first Salvia trip, all of my Salvia experiences have been representations of how our reality and universe is constructed and operated. From this experience, and many others like it, I have come up with what I feel is a very accurate portrayel of Salvia: 'Salvia allows the mind to travel and vividly witness one of the infinite possibilities in which our reality is operated.'
Of course, this may just apply to me.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


Bitcoin (Player A) |
Ethereum (Player B) |
|
I want to swap BTC for ETH secret: secretHash: A: Initiate Swapvalue: recipientAddress: refundAddress: secretHash: expiration: swap bytecode: transaction hash: B: Claim SwapWait until initiation transaction has been confirmed! secret: initiationTxHash: transaction hash: |
I want to swap ETH for BTC secret: secretHash: B: Initiate Swapvalue: recipientAddress: refundAddress: secretHash: expiration: swap bytecode: transaction hash: A: Claim SwapWait until initiation transaction has been confirmed! secret: initiationTxHash: transaction hash: |
For errors and logs, check console


HOME
ABOUT US
BRANDS
BLOG
EVENTS
SHOP
CONTACT US
SHOP BY BRAND
AMPLIFIERS
SPEAKERS
TURNTABLES
CD PLAYERS
STEAMERS
CABLES
FURNITURE
HEADPHONES
HOME CINEMA
OUTLET - SAVE UP TO 50% OFF
EBAY
CELLING SPEAKERS
TVS
VINYL LPS
SHOP NOW


Spring
Ethan Kessel
Week of January 9
I'm Ethan Kessel and I'm a Junior in AAE from Tucson, AZ. Some of my hobbies include digital drawing and cooking, and I'm a big tech nerd. I've been working on implementing a custom USB 3.0 hub for sensor integration on the IEEE ROV team and learning a lot about high-speed circuit design in the process.


Department of Advanced Science and Technology
University of Computer Studies
B.C.Sc/B.C.Tech. ( Third Year)
Computer Organization
Fianl Examination
Mathematics of Computing III(CST-302)
September, 2015
Zone III
Answer ALL Questions
Time allowed 3hours.
| [ | 6 2 -2 2 5 0 -2 0 7 |
] |
| A = | [ | √5 5 0 -√5 |
] |
9x1 + 6x2 + 12x3 = 17.4
6x1 + 13x2 + 11x3 = 23.6
12x1 + 11x2 + 26x3 = 30.8
| [ | 2 -1 1 -1 3 2 1 2 3 |
] |


--- layout: post title: DS cookbook date: 2006-08-22 00:00:00 categories: amusing mobile ---
Via ChewedMelon, Shaberu! DS O-Ryouri Navi : "a DS title that features over 200 recipes that are broken down to many steps and read aloud to you by the narrator. You can bark voice commands at your DS, such as "next page" and "more detail" for even simpler instructions."


Short Biography
Bradley Wiggins, in full Sir Bradley Marc Wiggins, byname Wiggo (born April 28, 1980, Ghent, Belgium), Belgian-born British cyclist who was the first rider from the United Kingdom to win the Tour de France (2012).
Wiggins’s early education in road racing was spent mainly in France with a succession of teams. It was not until his fourth-place finish in the 2009 Tour de France that Wiggins, who was previously regarded as a time-trial specialist, shot to prominence as a potential Tour winner. After switching to Team Sky, he took time to settle into his new role as team leader, finishing 24th in the 2010 Tour de France and crashing out of the 2011 race. In the 2012 road-race cycling season leading up to the Tour, he won the Paris–Nice, the Tour de Romandie, and the Critérium du Dauphiné, three of the biggest races on the professional calendar. A favourite entering the Tour de France, Wiggins took over the leader’s yellow jersey on stage seven and confirmed his historic win on the penultimate stage of the 23-day race after nearly 3,500 km (about 2,175 miles). His victory was widely regarded as evidence that the world’s toughest bicycle race could be won without the use of drugs, and Wiggins was applauded as a critic of doping in cycling; in a newspaper editorial published during 2012 Tour, Wiggins passionately explained why he refused to use performance-enhancing drugs.
Shortly after the Tour, Wiggins competed at the 2012 Olympics in London. There he won a gold medal in the time-trial event, becoming the first Tour de France champion to win Olympic gold on the track; he also became the only person to win the Tour and capture a gold medal in the same year. In 2013 he won the Tour of Britain. The following year he won a time-trial gold medal at the road world championships. At the Rio de Janeiro 2016 Olympic Games, Wiggins was part of a British squad that won gold in men’s team pursuit, bringing his lifetime Olympic medal total to eight, the most for any Briton. He retired from cycling in December 2016.
Wiggins was granted a knighthood in the 2013 New Year Honours list.


TEACHING
The courses I teach in NDHU include
Advanced Computer Programming
Introduction to Machine Learning
Multimedia Systems
Computer Programming (Intermediate Level)
Research
I am interested in doing research about
Deep Neural Networks
Machine Learning
Intelligent Human Machine Interfaces
Multimedia Systems and Applications
Computer Vision
Computer Hearing
Natural Language Processing
Virtual Reality and Augmented Reality
CONTACT US
If you need to contact us, please refer to the following information.
Cheng-Chin Chiang
Contact Information:
No. 1, Sect. 2, Dashueh Rd., Shoufeng, Taiwan, 974
<EMAIL_ADDRESS>+886 38905027


| G.A.R. 35 |
| [ See rule 149 ] |
| BILL FOR SCHOLARSHIP |
| Bill for scholarship tenable at...........................College/School
...........................................during
the month of........................19
........
|
|
| Sl.No. |
Year of award |
Kind of scholarship or stipend |
Name of scholarship or stipend holder |
Monthly value of scholarship |
No. of days for which drawn |
Amount drawn |
Remarks |
| 1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
| |
|
|
|
|
|
Rs. P. |
|
|
| Deduct balance undisbursed from |
| last month.................................... |
| Balance due.................................. |
| (In words).................................. |
| I hereby certify that the scholarship or stipend holders, named in this bill, have been regular in attendance
and have conformed to the rules under which their scholarships or stipends are tenable. |
| Certified also that the scholarships or stipends drawn on the last bill, with the exception of those refunded
by deduction, have been paid to the proper persons and their receipts taken in acquittance rolls kept
in my office. |
| Date.................................. |
Principal/Manager College/School
|
| |
| FOR USE IN DEPARTMENTAL OFFICE |
| Bill No........................................... |
| Head of Account........................................... |
Received the sum of Rs...........................................(Rupees
.........................................) being the amount sanctioned
by the .........................................under letter
......................................... No
.............................dated
..............................(Copy enclosed) for disbursement
to
.....................................
|
| Signature.................................. |
| Designation.................................. |
| Stamp of office.................................. |
| |
| (For use in pay and Accounts Office) |
| Passed for payment of Rs..................................(Rupees
..................................) |
| Payment by Cheque No........... |
| (To be indicated after delivery) |
| Dated........................................... |
Pay and Accounts Officerr |
|


the and with infected for The cells infection cell from were virus was are spreading that number cluster model clusters {background time can our which cultures distribution have culture data size Fig. experimental margin particles viral {border-style images GFP []. px;} #ffffff;} not than used very case percolation within after fractal here image probability resolution spread Click Figure LINK This additional file. well Video large medium results standard this using High [], astrocytes dimension each hours largest propagation their value also astroglial downloaded dynamics from: function its microscopic model. observed obtained one rate such titer two virus. about around being features into lattice observations simulation (Fig. been between both complex different experiment expression fixed highly http://amur.elte.hu/BDGVirus/ infection. infective parameters scale simple some system systems trees (see S). Virol above all average but during first fluorescent has high low more neighbours out over px; single stage supplementary {font-family (MPG) These based critical described due epidemics file fit font-size infect much plaques possible present random result scaling second software taken theory these treated units would BDG‐PRV Infectious PFU/ml PFU/ml) PRV Table Videos Virus agreement appearing astrocytic clusters. containing corresponding could cycle determined double; fields further growth having i.e., individual infectious larger likely order original power regions role same set show shows smaller spatial study susceptibility those videos when whole (,× (TIF) Cell Disease Experimental Our University []–[]. account actual already analysis appearance background because become behaviour border-color border-width carried cells. chosen cultures. defined designed early either experiments experiments, experiments. field following geometry given had human ii) increasing initial law lognormal long many models new obtain only overlap picture predictions primary processes quantitative randomly region seeds simulations sizes solid; stitched susceptible them there threshold through time-lapse tissue values variable {font-style {font-weight (e.g., After BDG Best Biology Budapest, Here ImageJ Listeria Materials Population Research Scale Shigella Viral allowed appear becomes bold bottom cells, characterization coins common considered constant courier; detailed details developed development distance distribution, dots em; every experimentally exponent exposed expressing formed gene generated grown hours, incubated instead involves known lead like made major method microscope neighbouring other overall phase place point process processing pseudorabies pt;} recombinant relatively representative respectively. resulting seen series setup significantly simplex statistical titer) type types under use visual vitro whether


I first began using Yerba Mate in 2003, after my uncle returned from Argentina with a gift of a “mate” (hollowed-out gourd) and a kilo of yerba (herb) to fill it with. I have been an avid user ever since, using it in lieu of coffee to increase my mental alertness and physical endurance. Bonus side effects include increased sweating and very regular bowel movements.
After I finished my first kilo, I sought out more in my local Latin markets
Preparation:
In the first couple of years, I used the traditional gourd and bombilla (a metal straw with a built-in strainer). I would fill the gourd about a third of the way with the herb and then fill it with hot water poured out of a thermos. (The water was poured into the thermos boiling.) This did a fine job, but after a while, my gourd began to develop mould on the inside that gave it a distinct smell. Apparently, this is desirable for the “body” it gives the brewed drink — and it was not unpleasant at first — but it did become a little too funky for my liking later on. At this point, I tossed out the gourd and bought myself a one-cup Bodum French press. Now I wish I had brewed my yerba mate this way from the beginning; it is the superior method of making mate, and no South American will ever convince me otherwise.
To make yerba mate in a French press, I put about two tablespoons of herb in the cylinder and moisten with a little water. This apparently helps to protect the nutrients within the herb. I next, boil my water. They recommend heating it to 70 degrees C, but I simply take my kettle off when it starts boiling and wait for the bubbling to settle down. Around that time, it should be cool enough that it won’t damage the nutrients or draw out any undesirable flavours.
I Cover the press with the plunger up and let the mate steep for a couple of minutes (I’d say 2-5, depending on how strong I like it). At this point, I may add sweetener if I like. A teaspoon of honey should do the trick. Lift the top off the press and swirl it right in. (I don’t use sweetener anymore, as the earthy taste of the tea gives me a Pavlovian sense of satisfaction as I anticipate the effects to come.). Next, I push down on the plunger slowly until I’ve packed the herb down. Let it sit for half a minute or so to let the sediment sink, and then pour slowly into my mug or teacup. A nice Asian or earthenware teacup would be fitting, but my plain old coffee mug suits me just fine.
That’s it. I sip it slowly for more prolonged effects, and reuse the leaves in the cylinder to make another cup, if I like. It will be milder, but it won’t lack kick.
Effects:
I receive hours of mental and physical stimulation from two cups of the brew described above. I am able to concentrate for longer periods of time, I find I slouch less at my desk, and I am much less prone to distractions, zeroing in on my tasks as if I had blinders on. Any more than two cups makes me feel a little racy, although the effects are much milder than those of straight black coffee. Also, during this period, sweating increases dramatically, urination increases, and my stools become very soft, allowing me to completely void my bowels (or at least it feels this way); in short, I feel a general sense of wellbeing and energy. Part of this could be a placebo effect due to my knowledge that yerba mate, if brewed correctly, contains a host of vitamins, minerals, amino acids, and antioxidants, but mostly I am just happy that I can enjoy a safe, legal beverage that gives me all of the benefits of coffee — and many more — with little to none of the side effects.
As with any stimulant, there are negative side effects, including irritability and fogginess if I cannot get my hands on a cup the next day (although this is much less pronounced than with caffeine — no headaches), raciness if I drink too much (although without the outright jumpiness and heart palpitations that caffeine gives me), and frequent urination
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


Our {{ projectName }} team
| Role | Name | ||
| {{ teamMember.role}} | {{ teamMember.name }} | [+] | |
|
Primary location: {{ teamMember.primaryLocation }} {% endif %} {% if teamMember.secondaryLocation %}Secondary location: {{ teamMember.secondaryLocation}} {% endif %}Email: {{ teamMember.email }} {% endif %} {% if teamMember.mobile %}Mobile: {{ teamMember.mobile}} {% endif %} {% if teamMember.slack %}Slack: {{ teamMember.slack}} {% endif %} {% if teamMember.skype %}Skype: {{ teamMember.skype }} {% endif %} |
|||


LEGAL
Terms of Service
These Terms of Service (“Terms”) govern your access to and use of the services, including our various websites, SMS, APIs, email notifications, applications, buttons, widgets, ads, and commerce services (the “Services” or “Airvoz”), and any information, text, graphics, photos or other materials uploaded, downloaded or appearing on the Services (collectively referred to as “Content”). Your access to and use of the Services are conditioned on your acceptance of and compliance with these Terms. By accessing or using the Services you agree to be bound by these Terms.
- Basic Terms:
You are responsible for your use of the Services, for any Content you post to the Services, and for any consequences thereof. The Content you submit, post, or display will be able to be viewed by other users of the Services and through third party services and websites. You should only provide Content that you are comfortable sharing with others under these Terms.
Tip: What you say on Airvoz may be viewed all around the world. You are what you Airvoz!
You may use the Services only if you can form a binding contract with Airvoz and are not a person barred from receiving services under the laws of the United States or other applicable jurisdiction. If you are accepting these Terms and using the Services on behalf of a company, organization, government, or other legal entity, you represent and warrant that you are authorized to do so. You may use the Services only in compliance with these Terms and all applicable local, state, national, and international laws, rules and regulations.
The Services that Airvoz provides are always evolving and the form and nature of the Services that Airvoz provides may change from time to time without prior notice to you. In addition, Airvoz may stop (permanently or temporarily) providing the Services (or any features within the Services) to you or to users generally and may not be able to provide you with prior notice. We also retain the right to create limits on use and storage at our sole discretion at any time without prior notice to you.
The Services may include advertisements, which may be targeted to the Content or information on the Services, queries made through the Services, or other information. The types and extent of advertising by Airvoz on the Services are subject to change. In consideration for Airvoz granting you access to and use of the Services, you agree that Airvoz and its third party providers and partners may place such advertising on the Services or in connection with the display of Content or information from the Services whether submitted by you or others.
- Privacy
Any information that you provide to Airvoz is subject to our Privacy Policy, which governs our collection and use of your information. You understand that through your use of the Services you consent to the collection and use (as set forth in the Privacy Policy) of this information, including the transfer of this information to the United States and/or other countries for storage, processing and use by Airvoz. As part of providing you the Services, we may need to provide you with certain communications, such as service announcements and administrative messages. These communications are considered part of the Services and your Airvoz account, which you may not be able to opt-out from receiving.
Tip: You can opt-out of most communications from Airvoz including our newsletter, new features emails, etc.
- Passwords
You are responsible for safeguarding the password that you use to access the Services and for any activities or actions under your password. We encourage you to use “strong” passwords (passwords that use a combination of upper and lower case letters, numbers and symbols) with your account. Airvoz cannot and will not be liable for any loss or damage arising from your failure to comply with the above.
- Content on the Services
All Content, whether publicly posted or privately transmitted, is the sole responsibility of the person who originated such Content. We may not monitor or control the Content posted via the Services and, we cannot take responsibility for such Content. Any use or reliance on any Content or materials posted via the Services or obtained by you through the Services is at your own risk.
We do not endorse, support, represent or guarantee the completeness, truthfulness, accuracy, or reliability of any Content or communications posted via the Services or endorse any opinions expressed via the Services. You understand that by using the Services, you may be exposed to Content that might be offensive, harmful, inaccurate or otherwise inappropriate, or in some cases, postings that have been mislabeled or are otherwise deceptive. Under no circumstances will Airvoz be liable in any way for any Content, including, but not limited to, any errors or omissions in any Content, or any loss or damage of any kind incurred as a result of the use of any Content posted, emailed, transmitted or otherwise made available via the Services or broadcast elsewhere.
- Your Rights
You retain your rights to any Content you submit, post or display on or through the Services. By submitting, posting or displaying Content on or through the Services, you grant us a worldwide, non-exclusive, royalty-free license (with the right to sublicense) to use, copy, reproduce, process, adapt, modify, publish, transmit, display and distribute such Content in any and all media or distribution methods (now known or later developed).
Tip: This license is you authorizing us to make your Airvoz available to the rest of the world and to let others do the same.
You agree that this license includes the right for Airvoz to provide, promote, and improve the Services and to make Content submitted to or through the Services available to other companies, organizations or individuals who partner with Airvoz for the syndication, broadcast, distribution or publication of such Content on other media and services, subject to our terms and conditions for such Content use.
Tip: Airvoz has an evolving set of rules for how ecosystem partners can interact with your Content. These rules exist to enable an open ecosystem with your rights in mind. But what’s yours is yours – you own your Content (and your photos are part of that Content).
Such additional uses by Airvoz, or other companies, organizations or individuals who partner with Airvoz, may be made with no compensation paid to you with respect to the Content that you submit, post, transmit or otherwise make available through the Services.
We may modify or adapt your Content in order to transmit, display or distribute it over computer networks and in various media and/or make changes to your Content as are necessary to conform and adapt that Content to any requirements or limitations of any networks, devices, services or media.
You are responsible for your use of the Services, for any Content you provide, and for any consequences thereof, including the use of your Content by other users and our third party partners. You understand that your Content may be syndicated, broadcast, distributed, or published by our partners and if you do not have the right to submit Content for such use, it may subject you to liability. Airvoz will not be responsible or liable for any use of your Content by Airvoz in accordance with these Terms. You represent and warrant that you have all the rights, power and authority necessary to grant the rights granted herein to any Content that you submit.
- Your License To Use the Services
Airvoz gives you a personal, worldwide, royalty-free, non-assignable and non-exclusive license to use the software that is provided to you by Airvoz as part of the Services. This license is for the sole purpose of enabling you to use and enjoy the benefit of the Services as provided by Airvoz, in the manner permitted by these Terms.
- Airvoz Rights
All right, title, and interest in and to the Services (excluding Content provided by users) are and will remain the exclusive property of Airvoz and its licensors. The Services are protected by copyright, trademark, and other laws of both the United States and foreign countries. Nothing in the Terms gives you a right to use the Airvoz name or any of the Airvoz trademarks, logos, domain names, and other distinctive brand features. Any feedback, comments, or suggestions you may provide regarding Airvoz, or the Services is entirely voluntary and we will be free to use such feedback, comments or suggestions as we see fit and without any obligation to you.
- Restrictions on Content and Use of the Services
Please review the Airvoz Rules (which are part of these Terms) to better understand what is prohibited on the Service. We reserve the right at all times (but will not have an obligation) to remove or refuse to distribute any Content on the Services, to suspend or terminate users, and to reclaim usernames without liability to you. We also reserve the right to access, read, preserve, and disclose any information as we reasonably believe is necessary to :
- satisfy any applicable law, regulation, legal process or governmental request.
- enforce the Terms, including investigation of potential violations hereof.
- detect, prevent, or otherwise address fraud, security or technical issues.
- respond to user support requests, or
- protect the rights, property or safety of Airvoz, its users and the public.
Tip Airvoz does not disclose personally identifying information to third parties except in accordance with our Privacy Policy.
Except as permitted through the Services, these Terms, or the terms provided on our developer’s agreement, you have to use the Airvoz API if you want to reproduce, modify, create derivative works, distribute, sell, transfer, publicly display, publicly perform, transmit, or otherwise use the Content or Services.
Tip: We encourage and permit broad re-use of Content. The Airvoz API exists to enable this.
If you use commerce features of the Services that require credit or debit card information, such as our Rent your Beacon feature, you agree to our Airvoz Commerce Terms.
You may not do any of the following while accessing or using the Services:
- access, tamper with, or use non-public areas of the Services, Airvoz’s computer systems, or the technical delivery systems of Airvoz’s providers
- probe, scan, or test the vulnerability of any system or network or breach or circumvent any security or authentication measures
- access or search or attempt to access or search the Services by any means (automated or otherwise) other than through our currently available, published interfaces that are provided by Airvoz (and only pursuant to those terms and conditions), unless you have been specifically allowed to do so in a separate agreement with Airvoz (NOTE: crawling the Services is permissible if done in accordance with the provisions of the robots.txt file, however, scraping the Services without the prior consent of Airvoz is expressly prohibited)
- forge any TCP/IP packet header or any part of the header information in any email or posting, or in any way use the Services to send altered, deceptive or false source-identifying information; or
- interfere with, or disrupt, (or attempt to do so), the access of any user, host or network, including, without limitation, sending a virus, overloading, flooding, spamming, mail-bombing the Services, or by scripting the creation of Content in such a manner as to interfere with or create an undue burden on the Services.
- Copyright Policy
Airvoz respects the intellectual property rights of others and expects users of the Services to do the same. We will respond to notices of alleged copyright infringement that comply with applicable law and are properly provided to us. If you believe that your Content has been copied in a way that constitutes copyright infringement, please provide us with the following information:
- a physical or electronic signature of the copyright owner or a person authorized to act on their behalf
- identification of the copyrighted work claimed to have been infringed
- identification of the material that is claimed to be infringing or to be the subject of infringing activity and that is to be removed or access to which is to be disabled, and information reasonably sufficient to permit us to locate the material
- your contact information, including your address, telephone number, and an email address
- a statement by you that you have a good faith belief that use of the material in the manner complained of is not authorized by the copyright owner, its agent, or the law; and
- a statement that the information in the notification is accurate, and, under penalty of perjury, that you are authorized to act on behalf of the copyright owner.
We reserve the right to remove Content alleged to be infringing without prior notice, at our sole discretion, and without liability to you. In appropriate circumstances, Airvoz will also terminate a user’s account if the user is determined to be a repeat infringer. Our designated copyright agent for notice of alleged copyright infringement appearing on the Services is:
GPMEC, Inc.
Attn: Copyright Agent
310 Dominion Rd NE
Vienna, VA 22180
Email<EMAIL_ADDRESS>- Ending These Terms
The Terms will continue to apply until terminated by either you or Airvoz as follows.
You may end your legal agreement with Airvoz at any time for any reason by deactivating your accounts and discontinuing your use of the Services. You do not need to specifically inform Airvoz when you stop using the Services. If you stop using the Services without deactivating your accounts, your accounts may be deactivated due to prolonged inactivity under our Inactive Account Policy.
We may suspend or terminate your accounts or cease providing you with all or part of the Services at any time for any reason, including, but not limited to, if we reasonably believe:
- you have violated these Terms or the Airvoz Rules,
- you create risk or possible legal exposure for us; or
- our provision of the Services to you is no longer commercially viable. We will make reasonable efforts to notify you by the email address associated with your account or the next time you attempt to access your account.
In all such cases, the Terms shall terminate, including, without limitation, your license to use the Services, except that the following sections shall continue to apply: 4, 5, 7, 8, 10, 11, and 12.
Nothing in this section shall affect Airvoz’s rights to change, limit or stop the provision of the Services without prior notice, as provided above in section 1.
- Disclaimers and Limitations of Liability
Please read this section carefully since it limits the liability of Airvoz and its parents, subsidiaries, affiliates, related companies, officers, directors, employees, agents, representatives, partners, and licensors (collectively, the “Airvoz Entities”). Each of the subsections below only applies up to the maximum extent permitted under applicable law. Some jurisdictions do not allow the disclaimer of implied warranties or the limitation of liability in contracts, and as a result the contents of this section may not apply to you. Nothing in this section is intended to limit any rights you may have which may not be lawfully limited.
- The Services are Available “AS-IS”
Your access to and use of the Services or any Content are at your own risk. You understand and agree that the Services are provided to you on an “AS IS” and “AS AVAILABLE” basis. Without limiting the foregoing, to the maximum extent permitted under applicable law, THE AIRVOZ ENTITIES DISCLAIM ALL WARRANTIES AND CONDITIONS, WHETHER EXPRESS OR IMPLIED, OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
The Airvoz Entities make no warranty and disclaim all responsibility and liability for:
- the completeness, accuracy, availability, timeliness, security or reliability of the Services or any Content;
- any harm to your computer system, loss of data, or other harm that results from your access to or use of the Services or any Content;
- the deletion of, or the failure to store or to transmit, any Content and other communications maintained by the Services; and
- whether the Services will meet your requirements or be available on an uninterrupted, secure, or error-free basis. No advice or information, whether oral or written, obtained from the Airvoz Entities or through the Services, will create any warranty not expressly made herein.
- Links
The Services may contain links to third-party websites or resources. You acknowledge and agree that the Airvoz Entities are not responsible or liable for:
- the availability or accuracy of such websites or resources; or
- the content, products, or services on or available from such websites or resources. Links to such websites or resources do not imply any endorsement by the Airvoz Entities of such websites or resources or the content, products, or services available from such websites or resources. You acknowledge sole responsibility for and assume all risk arising from your use of any such websites or resources.
- Limitation of Liability
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE AIRVOZ ENTITIES SHALL NOT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL OR PUNITIVE DAMAGES, OR ANY LOSS OF PROFITS OR REVENUES, WHETHER INCURRED DIRECTLY OR INDIRECTLY, OR ANY LOSS OF DATA, USE, GOOD-WILL, OR OTHER INTANGIBLE LOSSES, RESULTING FROM
- YOUR ACCESS TO OR USE OF OR INABILITY TO ACCESS OR USE THE SERVICES;
- ANY CONDUCT OR CONTENT OF ANY THIRD PARTY ON THE SERVICES, INCLUDING WITHOUT LIMITATION, ANY DEFAMATORY, OFFENSIVE OR ILLEGAL CONDUCT OF OTHER USERS OR THIRD PARTIES;
- ANY CONTENT OBTAINED FROM THE SERVICES; OR
- UNAUTHORIZED ACCESS, USE OR ALTERATION OF YOUR TRANSMISSIONS OR CONTENT.
IN NO EVENT SHALL THE AGGREGATE LIABILITY OF THE AIRVOZ ENTITIES EXCEED THE GREATER OF ONE HUNDRED U.S. DOLLARS (U.S. $100.00) OR THE AMOUNT YOU PAID AIRVOZ, IF ANY, IN THE PAST SIX MONTHS FOR THE SERVICES GIVING RISE TO THE CLAIM.

- General Terms
- Waiver and Severability
The failure of Airvoz to enforce any right or provision of these Terms will not be deemed a waiver of such right or provision. In the event that any provision of these Terms is held to be invalid or unenforceable, then that provision will be limited or eliminated to the minimum extent necessary, and the remaining provisions of these Terms will remain in full force and effect.
- Controlling Law and Jurisdiction
These Terms and any action related thereto will be governed by the laws of the State of Virginia without regard to or application of its conflict of law provisions or your state or country of residence. All claims, legal proceedings or litigation arising in connection with the Services will be brought solely in the federal or state courts located in Fairfax County, Virginia, United States, and you consent to the jurisdiction of and venue in such courts and waive any objection as to inconvenient forum.
If you are a federal, state, or local government entity in the United States using the Services in your official capacity and legally unable to accept the controlling law, jurisdiction or venue clauses above, then those clauses do not apply to you. For such U.S. federal government entities, these Terms and any action related thereto will be governed by the laws of the United States of America (without reference to conflict of laws) and, in the absence of federal law and to the extent permitted under federal law, the laws of the State of Virginia (excluding choice of law).
- Entire Agreement
These Terms, the Airvoz Rules and our Privacy Policy are the entire and exclusive agreement between Airvoz and you regarding the Services (excluding any services for which you have a separate agreement with Airvoz that is explicitly in addition or in place of these Terms), and these Terms supersede and replace any prior agreements between Airvoz and you regarding the Services. Other than members of the group of companies of which GLOBAL PRODUCTIVITY MANAGEMENT AND ENTREPRENEURIAL CONSULTING GROUP (GPMEC), Inc. is the parent, no other person or company will be third party beneficiaries to the Terms.
We may revise these Terms from time to time, the most current version will always be at Airvoz.com/tos. If the revision, in our sole discretion, is material we will notify you via an e-mail to the email associated with your account. By continuing to access or use the Services after those revisions become effective, you agree to be bound by the revised Terms.
These Services are operated and provided by GPMEC Inc., 310 Dominion Rd, Vienna, VA 22180. If you have any questions about these Terms, please contact us.
Effective: November 8, 2015