text:
# generate c file for readonly lookup
phash keyfile --prefix=phash -nul
# pure-perl usage
use Perfect::Hash;
my @dict = split/\n/,`cat /usr/share/dict/words`;
my $ph = Perfect::Hash->new(\@dict, -minimal);
for (@ARGV) {
my $v = $ph->perfecthash($_);
print ($dict[$v] eq $_ ? "$_ at line ".$v+1."\n" : "$_ not found\n");
Perfect::Hash->new("keyfile", '-urban', ...)->save_c;
# or just:
phash keyfile --urban
cc -O3 -msse4.2 phash.c ... -lz
phash /usr/share/dict/words --cmph-bdz_ph --nul
cc -O3 phash.c ... -lcmph
phash knows about several fast lookup algorithms for any readonly
string-based maps (no integer maps yet), and will select the best
method to store it as a lookup method in a C file to compile it with
your project. Such as with
gperf, only better. Planned are also
exporters for other languages, to be able to store values in their
native language-specific format. E.g. XS for perl-specific SVs, AVs or
In order to optimize loading of static data, readonly hashes to
cdb or
sqlite databases or serialized caches we will use
gperf was enhanced for
libunistring, to lookup unicode data
efficiently, compared to
icu which uses only straight C++ hashmaps.
Searching in constant tables is quite a remarkably common task, so I
am constantly suprised why nobody uses optimized data structures and
algorithms to use it. I only know of google which also use
consistent hashes
to spread the load and keyspace across several servers, apple for
their speach apps, and libunistring for unicode mappings.
e.g. could easily use perfect hashes instead of overly simple DJB
hashes. Or
mysql which is mostly only usable as glorified readonly
concurrent hashtable could be replaced by such tables. The update with
regeneration and recompilation for such a table costs less then a
typical update into mysql.
Let's create some sample hash tables:
$ phash /usr/share/dict/words -hanovpp -size 20 -false-positives
$ cat phash.c
#include "phash.h"
#include <string.h>
#ifdef _MSC_VER
#define INLINE __inline
#define INLINE inline
/* FNV algorithm from http://isthe.com/chongo/tech/comp/fnv/ */
static INLINE
unsigned phash_hash(unsigned d, const unsigned char *s, const int l) {
int i = 0;
if (!d) d = 0x01000193;
for (; i < l; i++) {
d = (d * 0x01000193) ^ *s++;
return d & 0xffffffff;
long phash_lookup(const unsigned char* s) {
unsigned char h;
signed char d;
char v;
/* hash indices, direct < 0, indirect > 0 */
static const signed char G[] = {
-16, 1, 1,-15, 0, 0, 0,-14, 1,-13,-12, 1, 3,-10, 0, -8,
0, -7, 0, -2,
/* values */
static const unsigned char V[] = {
0, 9, 17, 6, 12, 13, 10, 14, 18, 5, 8, 15, 4, 2, 11, 16,
1, 7, 3, 19,
long l = strlen(s);
h = (unsigned char)(phash_hash(0, s, l) % 20);
d = G[h];
v = d < 0
? V[(unsigned char)-d-1]
: d == 0
? V[h]
: V[(unsigned char)(phash_hash(d, s, l) % 20)];
return v;
This creates an interim lookup array
G with negative indices for
immediate in the values array
V, and with positive indices for a second
hash-based lookup into the values array
V, where the index is the hash
seed > 0. So we have typically 1.5 hash function calls per lookup.
Generation of such a table is linear in time, intermediate and resulting
space is
2n, one
array[n] for
G and another for the values. But note that
this lookup will only work if we know in advance that the key is a member of
the perfect hash. That's why we can use the option
In order to use arbitrary keys for the lookup, we omit
-false-positives, we need to add
a final check if the found key is really contained in the stored perfect hash.
So we need
3n space, one more array for the keys also, and one more full
We will also add the option
-nul to be able to store binary keys, with
NUL characters. Note that using \0 in keyfiles is quite tricky.
$ phash /usr/share/dict/words -hanovpp -size 20 -nul
$ tail -n30 phash.c
long phash_lookup(const unsigned char* s, int l) {
unsigned char h;
signed char d;
char v;
/* hash indices, direct < 0, indirect > 0 */
static const signed char G[] = {
-16, 1, 1,-15, 0, 0, 0,-14, 1,-13,-12, 1, 3,-10, 0, -8,
0, -7, 0, -2,
/* values */
static const unsigned char V[] = {
0, 9, 17, 6, 12, 13, 10, 14, 18, 5, 8, 15, 4, 2, 11, 16,
1, 7, 3, 19,
/* keys */
static const char* K[] = {
h = (unsigned char)(phash_hash(0, s, l) % 20);
d = G[h];
v = d < 0
? V[(unsigned char)-d-1]
: d == 0
? V[h]
: V[(unsigned char)(phash_hash(d, s, l) % 20)];
if (memcmp(K[v],s,l)) v = -1;
return v;
The differences are the additional storage of the
keys and the final
if (memcmp(K[v],s,l)) v = -1;
Note that this data structure here is optimized to work with
zero-based integer values. For arbitrary values the check would be a
bit different and we would need one more array for the values.
creates an array of key + value structs and the values can be of any
-hanovpp -
pp stands for pure-perl,
hanov for Steve Hanov,
who wrote a simple python script at
http://stevehanov.ca/blog/index.php?id=119 based on the cmph CHD
algorithm - method is the default method to create arbitrary sized
perfect hashes, and needs no external library. It creates pure and
independent, pretty fast C code.
The optimized versions
-hanov and
-urban use the
typically faster hardware accelerated
iSCSI CRC32 function from
which uses only 1 CPU cycle per word, but requires zlib on the system,
and is only fast if zlib is fast. You cannot beat 1 cycle, but some
zlib versions only use the slow software fallback version for CRC32,
which is most slower than the simple FNV hash function used with
Note that faster wordsize optimized FNV variants are "presented" at http://www.sanmayce.com/Fastest_Hash/index.html#TRIADvsCRC (Beware of eye-bleeding though)
gperf might be able to create even faster and better hashes, because
it doesn't fully hash each key, it rather creates a custom simpler
hash function for each key set. It just adds some characters at
certain indices until you get different values for each key. Most
other methods only create custom hash seeds for each keyset. But
gperf can not reliably create stable hash functions and will either
time out on certain keysets or will create bad hash tables.
The major variants of
phash -gperf include the options
-pic and
-pic creates a lookup function optimized for shared
libraries, and
-switch creates a nested switch statement.
gperf --switch=2 is by far worse than my optimized version called
phash -switch
With gperf you have to manually specify the level of nested switches, with
phash -switch the nesting level is created automatically, but the biggest trick
is a special memcmp optimization for shorter strings.
The old
gperf --switch=n variant:
$ gperf examples/words20 --switch=2
... special hash ...
const char *
in_word_set (str, len)
register const char *str;
register unsigned int len;
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) {
register int key = hash (str, len);
if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) {
register const char *resword;
if (key < 16) {
switch (key - 1) {
case 0: resword = "A"; goto compare;
case 2: resword = "A's"; goto compare;
case 3: resword = "AM's"; goto compare;
case 4: resword = "ATM's"; goto compare;
case 5: resword = "Aachen"; goto compare;
case 8: resword = "AZ's"; goto compare;
case 9: resword = "AZT's"; goto compare;
case 10: resword = "AWOL's"; goto compare;
case 13: resword = "AC's"; goto compare;
case 14: resword = "ASL's"; goto compare;
} else {
switch (key - 16) {
case 0: resword = "ACTH's"; goto compare;
case 1: resword = "ASCII's"; goto compare;
case 2: resword = "AOL"; goto compare;
case 3: resword = "AI's"; goto compare;
case 4: resword = "AOL's"; goto compare;
case 5: resword = "AIDS's"; goto compare;
case 8: resword = "AB's"; goto compare;
case 9: resword = "ABM's"; goto compare;
case 13: resword = "AA's"; goto compare;
case 14: resword = "ATP's"; goto compare;
return 0;
if (*str == *resword && !strcmp (str + 1, resword + 1))
return resword;
return 0;
vs. the new seperate
phash -switch method:
$ phash examples/words20 -switch
$ cat phash.c
#include "phash.h"
#include <string.h>
long phash_lookup(const unsigned char* s, int l) {
switch (l) {
case 1:
return *(s) == 'A' ? 0 : -1;
case 3:
switch (s[1]) { /* A's, AOL */
case 39:
if (*(short*)s == (short)0x2741 /* A's */
&& *(&s[2]) == 's') return 1;
case 'O':
if (*(short*)s == (short)0x4f41 /* AOL */
&& *(&s[2]) == 'L') return 10;
return -1;
return -1;
case 4:
switch (s[1]) { /* AM's, AB's, AZ's, AA's, AI's, AC's */
case 'A':
if (*(int*)s == (int)0x73274141 /* AA's */) return 2;
case 'B':
if (*(int*)s == (int)0x73274241 /* AB's */) return 3;
case 'C':
if (*(int*)s == (int)0x73274341 /* AC's */) return 5;
case 'I':
if (*(int*)s == (int)0x73274941 /* AI's */) return 7;
case 'M':
if (*(int*)s == (int)0x73274d41 /* AM's */) return 9;
case 'Z':
if (*(int*)s == (int)0x73275a41 /* AZ's */) return 17;
return -1;
return -1;
case 5:
switch (s[1]) { /* ATP's, AOL's, ASL's, ATM's, ABM's, AZT's */
case 'B':
if (*(int*)s == (int)0x274d4241 /* ABM's */
&& *(&s[4]) == 's') return 4;
case 'O':
if (*(int*)s == (int)0x274c4f41 /* AOL's */
&& *(&s[4]) == 's') return 11;
case 'S':
if (*(int*)s == (int)0x274c5341 /* ASL's */
&& *(&s[4]) == 's') return 13;
case 'T':
if (*(int*)s == (int)0x27505441 /* ATP's */
&& *(&s[4]) == 's') return 15;
if (*(int*)s == (int)0x274d5441 /* ATM's */
&& *(&s[4]) == 's') return 14;
case 'Z':
if (*(int*)s == (int)0x27545a41 /* AZT's */
&& *(&s[4]) == 's') return 18;
return -1;
return -1;
case 6:
switch (s[1]) { /* AIDS's, AWOL's, ACTH's, Aachen */
case 'C':
if (*(int*)s == (int)0x48544341 /* ACTH's */
&& *(short*)&s[4] == (short)0x7327 /* 's */) return 6;
case 'I':
if (*(int*)s == (int)0x53444941 /* AIDS's */
&& *(short*)&s[4] == (short)0x7327 /* 's */) return 8;
case 'W':
if (*(int*)s == (int)0x4c4f5741 /* AWOL's */
&& *(short*)&s[4] == (short)0x7327 /* 's */) return 16;
case 'a':
if (*(int*)s == (int)0x68636141 /* Aachen */
&& *(short*)&s[4] == (short)0x6e65 /* en */) return 19;
return -1;
return -1;
case 7:
return *(int*)s == (int)0x49435341 /* ASCII's */
&& *(short*)&s[4] == (short)0x2749 /* I's */
&& *(&s[6]) == 's' ? 12 : -1;
So we switch here first on the key length, and then on the best key.
The new switch method creates the nesting level automatically for you,
all cases with more than 3 comparisons are automatically changed to a
separate switch on the best character. And because we know the length
an the keys in advance we can optimize
memcmp away by doing
word-size comparison directly. This is 50% - 2000% faster then doing
memcmp on each string. See the implementation of the helper
I heard of people doing this on every string shorter than 128
chars. So far I'm using only 36 as cutoff.
This is not a very interesting example, you need much bigger keysizes to see smarter switch nesting in effect. With this method you can beat even the best hash functions for certain key sets.
For example we got with
/usr/share/dict/words on debian with size=
0.307571 seconds down to
0.006666 seconds, while the fastest perfect
hash needed
0.007391 seconds. See the benchmarks.
In this special case it was 200x faster with the new memcmp optimization method.
Unfortunately we cannot use this new memcmp optimization method for all hash tables. We need to know one string and the length to compare in advance, and the key and length is a parameter of the lookup method. This only works for this static switch table.
There exists another special hashing method, called Pearson hashing. This creates a short 256 bytes "pearson" table of randomized shuffled bytes and uses this table to mix with all characters of the string to hash. Such byte-wise operation with a small lookup table are perfect for smaller machines or smaller keysets.
In my benchmarks
-pearson wins with ~127 keys, but you need to be a
bit lucky to find a good pearson randomization. phash -pearson tries for
max 60 seconds to find the best random table.
Small dictionary with 127 keys
Method *lookup* generate compile c size exesize options
hanovpp 0.001247 0.001904 0.069912 3454 11575
hanov 0.001231 0.000946 0.070709 3200 11629
urban 0.001298 0.001020 0.072471 3200 11629
pearson 0.001178 0.068758 0.072311 12354 19240
pearsonnp 0.001253 0.018204 0.072419 12386 19259
cmph-bdz_ph 0.001271 0.000412 0.066264 335 10009
cmph-bdz 0.001317 0.000403 0.066471 424 10033
cmph-bmz 0.001277 0.000539 0.066814 2431 10577
cmph-chm 0.001325 0.000646 0.067026 4356 11057
cmph-fch 0.001372 0.000511 0.066843 942 10177
cmph-chd_ph 0.001310 0.000361 0.066292 418 10033
cmph-chd 0.001323 0.000343 0.066428 735 10129
switch 0.001190 0.000173 0.131323 12517 17450
gperf 0.001199 0.002180 0.064883 8987 12574
The generated code looks like this:
$ phash examples/words20 -pearson
$ cat phash.c
#include "phash.h"
#include <string.h>
long phash_lookup(const unsigned char* s) {
int l = strlen(s);
long h = 0;
const char *key = s;
static unsigned char phash[] = {
136,176, 67, 19,170, 84, 87,228, 86, 92,100,214,208,201,160,126,
30,192, 78,189,232,244,142,252,253,147, 34,251,156, 38, 62,141,
20, 69, 88, 36,241,193, 77,162, 48,247,181,234,194,125, 98,135,
127, 61,204,180,205,133,132,145, 10,146,229, 18,198, 37, 73,139,
70,131,249, 51,223,235, 97,202,120,165, 16, 7,186, 89,243, 24,
216, 43, 45,182, 0, 94, 2,248, 39,188,255,240,219, 96,220,217,
168,130, 1,190, 85, 75, 44,169, 55,144, 58,224,221,239, 12,159,
211, 90, 47, 72, 33, 8, 26,231, 56, 57,155, 59, 3,254, 66,185,
27, 4, 6,102,101,150, 63,153, 52, 81,197,105,161, 9,140, 11,
207,148,103,199,183, 49,213,143,149,138, 99,117,167, 83,171,175,
218, 53, 80,113,106,250,124,137,109,104, 22,242,107,134,166, 54,
14,110,164,236,187,203,237,154,128, 31, 15, 74,179,230,158,177,
115,210,114, 5,226,196,212, 60,116, 21,157, 32,112,238, 17, 41,
68,184, 93, 23,245,173,129,172, 25, 79,233,178, 28,121, 40,246,
119, 50, 13, 65,163,222,206, 95,225,122, 71,111, 46, 35,195, 82,
42,152, 76, 91,151,118, 29,209,174,227,108, 64,200,215,123,191,
/* collisions: keys and values */
static const int Cv_1[] = {0};
static const char *Ck_2[] = {"ABM's","AC's", };
static const int Cv_2[] = {4,5, };
static const int Cv_3[] = {7};
static const int Cv_4[] = {3};
static const int Cv_5[] = {2};
static const int Cv_6[] = {8};
static const int Cv_7[] = {1};
static const int Cv_8[] = {6};
static const int Cv_9[] = {9};
/* collision keys */
static const char *Ck[] = { 0, 0,
(void*)&Ck_2, 0, 0, 0, 0, 0, 0, 0, };
/* collision values and direct values */
static const int *Cv[] = { 0,
(void*)&Cv_9, };
/* size of collisions */
static const unsigned char Cs[] = { 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, };
/* keys */
static const char* K[] = {
unsigned char c;
for (c=*s++; c; c=*s++) {
h = phash[(h ^ c) % 256];
h = h % 10;
if (Cs[h] > 1) {
const char **ck = (const char **)Ck[h];
int i = 0;
for (; i < Cs[h]; i++) {
if (!memcmp(ck[i], key, l)) return Cv[h][i];
else if (Cs[h] == 1) {
h = Cv[h][0];
if (memcmp(K[h], key, l)) h = -1;
return h;
We see that
-pearson did not generate a perfect hash, it rather
created a static collision table. But
-pearson tries to
minimize the collision costs for us by trying random pearson tables
for a maximum time of 60 seconds and then stores the best variant.
In this example here we only got one colliding bucket with 2 values.
There are 2 variants for -pearson, called
-pearsonnp, "np" for non-perfect,
-pearson8 which is the strict perfect hash variant and a 8 bit table.
-pearsonnp will use a larger pearson lookup table to create less collisions,
-pearson8 will most likely fail to create a proper hash table. I'm also
still experimenting with other pearson variants for bigger tables.
The currently supported external variants (which require an external library even at run-time) use the cmph library. They are a bit slower than the other methods, but only a bit. They allow much bigger key sizes, with dictionaries which might even exceed your main memory, and there exists even an variant to use tables which exceed the available main memory.
$ phash examples/words20 -cmph-bdz_ph
$ cat phash.c
#include "phash.h"
#include <string.h>
#include "cmph.h"
long phash_lookup(const unsigned char* s) {
static unsigned char *packed_mphf = "\006\000\000\000\000\000\000\000\r\000\000\000\t\000\000
return cmph_search_packed(packed_mphf, (const char*)s, strlen(s));
You need to link this file with
Creating perfect hashes is easy,
they are grossly underused,
they are fast,
and in certain cases fast data tricks - word-sized cmp instead of memcmp - beat better algorithms.]]>
Our old compiler (with 5.6.2) needed 2:30 hours for each build, produced ~100 binaries of about 30-50MB size. This sounds a lot but it is not. This is about the size a single perl scripts needs in memory, but a single perl script has to find all the dependent files first, load and parse it, and construct the stashes, the nested hashes of namespaces. All this is not needed at all during run-time, hence perlcc compiled binaries do not need it. The new compiler uses 30 minutes for the same binaries on our build servers, but is not yet using a lot of internal optimizations. It does use a lot of statically initialized strings and data, so the run-time is better than with 5.6, even if 5.6 is still much faster than the 5.14 run-time. But we still don't collect arrays into _independent_comalloc ranges as we did with 5.6, we still don't use link-time nor profile guided optimizations and we still do not optimize single modules seperately.
There are not many shared libraries used in such a compiled binary, just libperl and the used XS shared libraries.
Starting such a single binary is very fast, it's just mapped into memory at once, then the dynamic symbols need to be generated, as B::C cannot yet generate them statically, and perl5 is not really helpful in supporting static symbols, but all other data, strings and ops (perl functions) are generated statically. Then the XS modules are initialized (booted), then some pointers pointing into some shared libraries need to updated, as they pointed to some other pointer at compile-time and then the perl program is started.
The plan for the next year is to support generating shared modules per
perl package.
perlcc -m compiles a package to a shared library,
buildcc generates the
Makefile.depend dependencies for each binary,
and then you can use selectively more advanced optimizations per
package. I.e. B::CC or rperl optimized compilations, which should run
2-20x faster than the current B::C compiled packages.
B::CC is not stable enough yet, so you can only use it with some modules, and it currently benefits greatly from type information, for which upstream maintainers have no interest. With rperl it is even more strict, as those modules are not even more strict, as in real programming languages compared to our simple dynamic scripting language, it explicitly disallows certain kinds of dynamic magic or array autovivification, which slows down run-time so much as benchmarked in my YAPC::EU 2013 talk.
So the plan is to compile to several optimized libraries seperately and link them together later. For binaries which fork or which need to be updated pretty often, shared libraries are preferred, for other simple binaries static libraries are preferred as they are loaded much faster. Shared libraries can be updated much easier, and when you fork a binary its shared libraries are shared, there's no seperate copy in memory. This is also one of the main reasons to change our current perl5 unicode implementation from simple and slow perl data structures, to compiled shared libraries, which are just mapped in when needed and can be shared.
But first some other steps are needed. Before we will create compiled
libraries per perl packages we want to compile only some read-only
datastructures, hashes mainly. The name of this module is
Data::Compile and will replace our current
cdb databases for
localization data. cdb maps readonly strings to strings, but cannot
store other values than strings and is implemented as normal hashmap.
Our localization data would be much easier to use with stored
coderefs, similar to pre-compiled html templates, which which is a mix
of strings and coderefs. By using certain parts of B::C it is trivial
to store data as shared library, which can be dynaloaded on
demand. Loading such a compiled datastructure of perl data is of
course much faster then loading a btree or colliding hashmap and accessing it at run-time
through some magic tie interface. B::C is very efficient in storing
perl data statically, and only some GV symbols need to be initialized
at boot-time.
Data::Compile will also replace the overly slow serializers, like
Data::MessagePack or
Storable, which
have to convert binary data from and to perl data.
freezes perl data natively and just thaws it at instance. So loading
the CPAN Metadata file will go from 16 secs to 0.001ms, similar to
CPAN::SQLite and
cpanm which does those queries at run-time to
some server will not be needed anymore. Updating such a compiled CPAN
Metadata file is estimated to need 2 secs, which needs about the same
time as updating CPAN with CPAN::SQLite. And CPAN::SQLite still has a
locking bug, which prevents multiple cpan sessions, so you are easier
of with cpanm now.
In order to optimize loading of static data, readonly hashes, to
cdb or
sqlite databases or serialized caches we need
another module first:
Currently there's is only
gperf to
create perfect hashes in C or C++, and then there is also the lesser
known bob jenkins
perfect executable
to create perfect hashes (with some weird header files) and of course
the cmph library to create perfect
hashes of bigger dictionaries, google size. No single database or
datra-structure can be faster to lookup then perfect hashes for
readonly data, the fastest single-host readonly databases are cdb and
mysql. And perfect hashes beat them by far. Ever wondered why Google
lookups are so fast? Well, they distribute hashes across several
servers with so-called
consistent hashes,
which map strings into buckets of
n servers, and when they insert
and delete entries the remapping (copying to other buckets) is
minimized. But the real trick are minimal perfect hashes, which
minimize lookup times and storage sizes far beyond normal or sparse
hashes or b-trees.
So I created
phash to replace
gperf in the long term, by using
better algorithms to handle any data (
gperf fails to work with
anagrams or weird keys), to create optimally fast C libraries or
optimally small C libraries for fast hash lookups, and even provide
backends to output perfect hashes for several popular programming
languages, like perl (XS), java, ruby, php or python. As C library
you can only store strings as keys, and integers and strings as
values. With those other backends you can store all supported values.
Perfect hashes look differently on small 8-bit machines than on fast
x86_64 machines, for static libraries or for shared libraries with
-fPIC, for <1000 keys or for >1.000.000 keys, for keys with NUL
characters or not, for 7-bit keys only, for unicode keys, for
case-insensitive key lookup, and much more. Using a high-level
language to analyze the keys to generate a good perfect hash (in this
case perl) is much easier than fixing and enhancing
The other main problem is
icu which is a collection of glorified but
moderately efficient hashmaps of unicode tables and the even worse
perl5 implementation of those unicode tables. Encode does it much
better by pre-compiling encoding tables into good shared libraries,
but unicode has much more tables than just encodings.
currently uses icu with a new
gperf generated workaround for missing
tables in icu (the not-existing whitespace class and missing
namealiases which were broken in icu 5.0), and
moarvm came up with
it's own implementation of those tables to workaround icu
So far I have re-implemented the best algorithms to create and use perfect hashes in pure perl and optimized it with XS functions and I am able to create good C code. I am still testing optimal hash functions and strategies. I need only ~2 seconds to create a perfect hash for 100.000 entries in pure perl, with C libraries this goes down to 0.001 seconds, scaling linearily. The main problem is solved. Compilation with a C compiler and -O3 of such hashes need another second.
E.g. these hashes can be used to replace the constant lookup in ExtUtils::Constants. So I'll look soon into seperate my current ~10 different implementations of perfect hashes into one simple but good enough pure-perl version, which will generate pure-c code, without the need for any external library, and then seperate the others into several packages with external dependencies, like zlib for a fast hardware-assisted crc32 hash function (1 op per word), or libcmph and the various output formatters.
Then Data::Compiled will use Perfect::Hash::XS to store the read-only hashes. And then source code will change to use those hashes instead, and then perlcc -m will be able to compile and link arbitrary perl packages with various type annotations and various compilers, if B::C -O0, -O3, B::CC -O0, -O2 or even rperl.
The next plan is then to create a type inferencer in C, but I'll wait for this until p5p comes to a syntax decision how to annotate return types of functions. If ever.]]>
Perfect::Hash::Urban the
size advantage is 3320 byte vs 88 bytes for two integer arrays of size
20 with values
[0..19], which compress to 8 bit per entry with
vec. This is 300x less bytes.
The theoretical maximal simple compression would be 13 byte,
i.e. 5 bits per entry * 20 = 100 bits = 13 byte. Stored as Perl PV
this would require 68 byte PV overhead + 13 byte for the bitvector.
But vec is only allowing sizes which are a power of 2, i.e. (1,2,4,8.16,32 and with 64 bit machines 64). So it seems to use natural words to store the bits, allowing fast access to each entry. With 64 bits it even throws a portable warning. I have no idea what this warning is for nowadays, other than Storable would not be able to thaw it on 32bit machines which do not support 64bit ints. Currently it hurts performance at every single get and set access at run-time for vec with 64 bits entries.
So I implemented my bitvector to store intermediate tables for my perfect hashes in pure-perl and XS with vec, and it was about 2x faster and 300x smaller. That's approximately what I expected.
# convert 2 int arrays @G and @V to one bitvector $G (a string)
my $bits = 1+length(sprintf "%b",$size); # +1 for negative values
for (2,4,8,16,32,($Config{ptrsize}==8?(64):())) {
next if $bits > $_;
$bits = $_; last;
my $G = "\0" x int($bits * $size / 4); # calloc it
for my $i (0..$#G) {
vec($G, $i, $bits) = $G[$i] if $G[$i];
# $G+offset = @V
for my $i (0..$#V) { # put V after G
vec($G, $i+$size, $bits) = $V[$i] if $V[$i];
printf("\$G\[$bits]=\"%s\":%d\n", unpack("h*", $G), length($G))
if $options{-debug};
and read-access is like this:
my $v = vec($G, $index, $bits); # vec version of $v = $G[$index];
But then I tried perfect hashes on bigger dictionaries, like
/usr/share/dict/words which need tables of 32 bits per entry, which
are needed for 65535 to 4294967295 entries. Note that with that many
entries a real bitvector, i.e. via Bit::Vector might be better than
the simple approach with vec, which does not support bit sizes between
16 and 32 or even in 32 - 64. But so far I prefer to work without any
external dependencies.
Everything works fine in pure-perl, but I wanted faster arithmetic and hash calculations in XS for bigger dictionaries. Like the CPAN Metadata hashes or the various perl5 unicode tables.
But my XS version did not work with bigger dictionaries, it only worked fine with 8 bit tables, which is for a maximum table size of 64.
My XS implementation of vec looked like this:
static inline
IV vec(char *G, IV index, IV bits) {
if (bits == 8)
return *(char*)(G + index) & 255;
else if (bits == 4)
return *(char*)(G + (index / 2)) & 15;
else if (bits == 16) {
short l = *(short*)((short*)G + index); /* __UINT16_MAX__ */
return (IV)l;
else if (bits == 32) {
#if INTSIZE == 4
int l = *(int*)((int*)G + index); /* __UINT32_MAX__ */
long l = *(long*)((long*)G + index);
return (IV)l;
#ifdef HAVE_QUAD
else if (bits == 64) {
long l = *(long*)((long*)G + index);
return (IV)l;
Every access translates to natural words and index offsets, which translates to a single assembler instruction per size. But I got overflows on most indices, so I looked up the perl5 implementation of vec in doop.c and started getting angry.
vec is really little-endian only, no natural endianness, so perl5 does byte fiddling for all the various sizes, but then the bit size limit makes no sense at all anymore, as the naive implementation supporting little-endian only would be a simple loop independent of the bits, instead of all the if branches to check the supported bit sizes. So perl5 vec is not only unnecessarily slow, and only supports little-endian, not native endian-ness, it also adds arbitrary limits on the supported bit sizes for no good technical reason.
So either use
Bit::Vector or pack/unpack instead. vec is good for
nothing. But I'll probably use just my fast nvec implementation for
natural endian-ness and natural word sizes as shown above. This is a drop-in replacement for
vec for bits>=4, but works with cooperative access for XS and Pure-Perl, and is fast.
0 3634661x
1 3263596x
2 4361350x
3 2745134x
4 4199196x
5 2921502x
... and so on linearly falling ...
29 1821569x
30 736893x
31 312185x
32 643500x
33 379865x
34 371403x
35 1050967x
36 1016470x
37 1226918x
38 8558286x
39 1671515x
40 4594200x
41 2859521x
42 627789x
43 686036x
67 220743x
68 3382026x
69 1225141x
70 147903x
71 95882x
307 8330x
308 8962x
309 7902x
310 9041x
513 2413x
514 2713x
515 2708x
516 1945x
1098 410x
1099 433x
1100 402x
1101 400x
1848 69x
2225 14756x
2226 66x
2283 14877x
2284 63x
2309 14818x
2310 60x
2658 25321x
2659 56x
4239 9221x
4240 53x
5654 23526x
5655 46x
6355 1799x
6356 41x
6768 1641x
6769 38x
7476 2001x
7477 35x
7983 37x
7984 76x
7985 27x
7989 25x
7990 23x
8292 54x
8293 19x
9716 18x
10132 19x
10133 18x
13060 1968x
13061 15x
19745 39503x
19746 13x
20893 3795x
20894 9x
22124 3862x
22125 5x
23647 3865x
23648 1x
25137 328x
0 1933x
1 294x
3 432x
7 24128585x
15 14099448x
31 15040566x
63 28189821x
127 19795904x
255 10955641x
511 3851922x
1023 2009591x
2047 961707x
4095 180486x
8191 236082x
16383 141396x
32767 136848x
0 19076114x
1 76051832x
2 19870023x
3 4091878x
4 577090x
5 46417x
6 16933x
7 346x
8 23x
It was produced with this patch and a short script to sum up the occurences of the hash keys, sizes and tried collisions. The tests are still work in progress, see some more in this perl-hash-stats repo
The perl5 testsuite has a key size of median = 20, and avg of 133.2. The most commonly used key sizes are 4, 101 and 2.
| Hash Function | collisions| cycles/hash |
Less collisions are better, less cycles/hash is faster. A hash table lookup consists of one constant hash function (depending only on the length of the key) and then resolving 0-x collisions (in our avg case 0-8).
So it's a pretty good distribution to test better hash tables. Sorry, no beautiful plots yet, later.
The problem I see with the new 5.18 hash tables is manifold:
I'm working on fixing the 5.18 hash table problem and also evaluating robin-hood (fastest open addressing hash table) and cmph BMZ (fastest perfect hash) and using HW optimized hash functions (crc32 intrinsincs and SSE4.2 or armv8).
My analysis of the ususal hash functions is here: github.com/rurban/smhasher, where you can see how ridicuously slow siphash is, how slow and bad jenkins is, compared to fast hash and more secure functions. There are also the results of the full testsuite for each hash function and the easier to follow stats) evaluating quality vs performance.
Good open addressing hash tables are evaluated at github.com/goossaert/hashmap.
Perfect hash tables are explained at cmph.sourceforge.net/.
The public motivation to slow down the perl hash function is here. The discussion within the security team is not available, but as I was told, only the actual attack is not published, which is good. What is not good is that the developers have no idea how to evaluate hash tables and there is no sane discussion possible in the mailinglist, hence this blog and the various repos. In the end I will submit the best solution as patch.
I am also working a symbolic proof besides the statistical one with the stp SAT solver, to see the "quality" of a hash function over the possible seeds, counting the number of collisions over the typical table sizes. With such a solver you can automatically create attack vectors against most web-sites with bad hash collision strategies, so I'm a bit reluctant to publish that.
Note that "hardening" a hash function does not help in hardening a hash table. It only will get slower, but only marginally better.
Notes: * Edited SIPHASH out. We are using jenkins_hard in blead now. This is 2x faster than siphash, and only 6x slower than unoptimized City, but 4-20x slower than SSE4 optimized crc32 intrinsics, with not that high additional collision costs. * Edited seed + len confusion. This is a good thing to do. In fact CRC32 is currently the leader in least collisions and performance.]]>
each hash iterator has two problems which almost nobody is aware
of, and which might lead to unexpected and hard to detect problems.
We were using the perl-compiler since 12 years in production and just
recently found out that the B function
walksymtable will miss random
symbols from time to time. It entirely depends on hash randomization.
I cannot predict what
each did to your code.
Adding or deleting a key might lead to rehashing, which will re-order the keys. The iterator will just continue and then either miss keys or get keys again a second time.
perldoc -f each:
If you add or delete a hash's elements while iterating over it, entries may be skipped or duplicated--so don't do that. Exception: It is always safe to delete the item most recently returned by "each()", so the following code works properly:
while (($key, $value) = each %hash) {
print $key, "\n";
delete $hash{$key}; # This is safe
Below is the bug fixed with http://perl5.git.perl.org/perl.git/commit/5cc8528c900964306cba9b53c6eaa27af540eaea?f=ext/B/B.pm but even the p5p committer was not able to understand the underlying problem, why it failed. This bug was in core perl since 5.005 (1998) until 5.18.
sub walksymtable {
my ($symref, $method, $recurse, $prefix) = @_;
my $sym;
my $ref;
my $fullname;
no strict 'refs';
$prefix = '' unless defined $prefix;
while (($sym, $ref) = each %$symref) {
$fullname = "*main::".$prefix.$sym;
if ($sym =~ /::$/) {
$sym = $prefix . $sym;
if (svref_2object(\*$sym)->NAME ne "main::"
&& $sym ne "<none>::"
&& &$recurse($sym))
walksymtable(\%$fullname, $method, $recurse, $sym);
} else {
The fix is to replace
while (($sym, $ref) = each %$symref)
foreach my $sym (keys %$symref) {
my $ref = $symref->{$sym};
walksymtable walks all entries in stashes (symbol table hashes) and
all its children, and calls a method on each symbol. There is no
apparent destructive code in walksymtable which could change the
stash, but calling methods might lead to changes. Here it's
->$method(). It could be totally unexpected, e.g. loading a module
which changes the symboltable or
@ISA hierarchy, which might lead to
skipped symbols. Or just parsing normal perl code, such as attributes
or named regex references will magically load code and change the
symbol table.
each is a bit more performant then foreach, because
foreach stores the list
to iterate over and just advances the index into it.
But you are still able to change entries in the hash with for/foreach, you
are safe to use recursion and you are safe from unexpected
side-effects as in the
walksymtable function.
while (($key, $value) = each %hash) {
use Data::Dumper;
print $key, "\n";
delete $hash{$key};
print Dumper(\%hash); # This is a bug
The problems is that
Data::Dumper internally uses each to iterate over
the hash, which resets the iterator of the hash to the end. The first
while loop will not be able continue, the iterator cannot even be
stored and reset manually.
This is a Data::Dumper bug not detected and fixed in core perl for 16
years, since perl 5.005 (1998).
each not being re-entrant is not even documented.
The hash iterators should have really been stored in the op, not the hash. This is one of the oldest perl5 bugs which will never be fixed.
So each should be treated as in php: Avoid it like a plague. Only use it in optimized cases where you know what you are doing, but not in libraries as you saw with Data::Dumper.]]>
Tested projects are so far: perl5, rakudo, nqp, parrot and p2.
The buildslaves are currently: centos5 (old system), cygwin, cygwin64, darwin (my macbook air), debian (fresh), mingw32 (strawberry), ppc (an old powerbook)
And soon: mingw64 (python refuses mingw64, demands msvc), freebsd, openbsd, solaris10 (intel 64bit)
All the slaves initiate the connection to the bot on some private tcp port, so they can all stay behind my firewall. Most of them are some vm's on my devbox, and I start/stop them at random.
The setup included installing python 2.7, setuptools, and then easy_install buildbot-slave. The configuration is a bit tricky, but it's python code, not just some data format, and not jenkins.
I currently only watch the main branches, not smoke-me. The biggest problem is that some projects are not "remake clean": git update + configure + make + make test might need a make clean or even a git clean -dxf before. This is fine if your smokers are big and fast, but my smokers are small and slow.
The UI is also not the best so far. I want to collect the projects into BuildSets, and eventually add bench mark data.
I already collected and fixed a couple of previously undetected bugs.
Eventually I'll add random CPAN module testing, against all my installed major perls on all these architectures. My old smoker just smoked the stable B::C against latest blead changes daily. And from time I get some cpantesters fail reports, but nothing helps in smoking beforehand and at once. There's some interface to add random builds via 'try'.
This is the buildbot master cfg:
# -*- python -*-
# ex: set syntax=python:
"ppc", "darwin",
builders = []
for p in projects:
for slave in allslaves:
name = p + "-" + slave
# This is the dictionary that the buildmaster pays attention to. We also use
# a shorter alias to save typing.
c = BuildmasterConfig = {}
# The 'slaves' list defines the set of recognized buildslaves. Each element is
# a BuildSlave object, specifying a unique slave name and password. The same
# slave name and password must be configured on the slave.
from buildbot.buildslave import BuildSlave
c['slaves'] = []
for slave in allslaves:
c['slaves'].append(BuildSlave(slave, "******"))
# 'slavePortnum' defines the TCP port to listen on for connections from slaves.
# This must match the value configured into the buildslaves (with their
# --master option)
c['slavePortnum'] = 9989
# the 'change_source' setting tells the buildmaster how it should find out
# about source code changes.
from buildbot.changes.gitpoller import GitPoller
c['change_source'] = []
# branches=True for all branches only with buildbot master (0.9)
# Configure the Schedulers, which decide how to react to incoming changes. In this
# case, just kick off a 'runtests' build
from buildbot.schedulers.basic import SingleBranchScheduler
from buildbot.schedulers.forcesched import ForceScheduler
from buildbot.changes import filter
c['schedulers'] = []
for p in projects:
names = []
for slave in allslaves:
names.append(p + "-" + slave)
# The 'builders' list defines the Builders, which tell Buildbot how to perform a build:
# what steps, and which slaves can execute them. Note that any particular build will
# only take place on one slave.
from buildbot.process.factory import BuildFactory
from buildbot.steps.source.git import Git
from buildbot.steps.shell import ShellCommand
factory = {}
factory[p] = BuildFactory()
# check out the source
factory[p].addStep(Git(repourl='git://github.com/parrot/parrot.git', mode='incremental'))
factory[p] = BuildFactory()
factory[p].addStep(Git(repourl='git://github.com/perl6/nqp.git', mode='incremental'))
# -j4 to be fixed with rotwang/parallel-make-gh152
factory[p] = BuildFactory()
factory[p].addStep(Git(repourl='git://github.com/rakudo/rakudo.git', mode='incremental'))
factory[p] = BuildFactory()
factory[p].addStep(Git(repourl='git://github.com/Perl/perl5.git', mode='incremental'))
factory[p] = BuildFactory()
factory[p].addStep(Git(repourl='git://github.com/perl11/p2.git', mode='incremental'))
from buildbot.config import BuilderConfig
c['builders'] = []
for p in projects:
for slave in allslaves:
name = p+"-"+slave
# 'status' is a list of Status Targets. The results of each build will be
# pushed to these targets. buildbot/status/*.py has a variety to choose from,
# including web pages, email senders, and IRC bots.
c['status'] = []
from buildbot.status import html
from buildbot.status.web import authz, auth
# change any of these to True to enable; see the manual for more
# options
gracefulShutdown = False,
forceBuild = 'auth', # use this to test your slave once it is set up
forceAllBuilds = False,
pingBuilder = False,
stopBuild = False,
stopAllBuilds = False,
cancelPendingBuild = False,
c['status'].append(html.WebStatus(http_port=8010, authz=authz_cfg))
# the 'title' string will appear at the top of this buildbot
# installation's html.WebStatus home page (linked to the
# 'titleURL') and is embedded in the title of the waterfall HTML page.
c['title'] = "Perl VM"
c['titleURL'] = "http://parrot.org/"
# the 'buildbotURL' string should point to the location where the buildbot's
# internal web server (usually the html.WebStatus page) is visible. This
# typically uses the port number set in the Waterfall 'status' entry, but
# with an externally-visible host name which the buildbot cannot figure out
# without some help.
c['buildbotURL'] = "https://perl514.cpanel.net:8010/"
c['db'] = {
# This specifies what database buildbot uses to store its state. You can leave
# this at its default for all but the largest installations.
'db_url' : "sqlite:///state.sqlite",
Basically we need to define compilation blocks for rperl (restricted perl) - typed and compile-time optimizable syntax - and combine it with unoptimizable dynamic perl5 syntax, to be able to run ordinary perl5 code, partially optimized.
B::C can compile dynamic perl5 syntax to C code and simply run the unoptimized optree through libperl. 10x better startup, destruction and 10% memory savings.
B::CC does control-flow and simple type optimizations, esp. on stack variables but has no proper type integration yet, and will never be able to run 100% of perl5 code. 2-5x better run-time. perl5 is a too dynamic language to be properly compilable as you would expect. But perl5 has support to parse and store types, just nobody is using it yet. And p5p does not support optimizations based on the type information, it rather blocks those attempts. So we need a seperate compilation to C (reini), C++ (will) or LLVM (goccy).
perlcc, the frontend, cannot compile yet .pm packages to single shared libraries and link it together, to be able to use different compile-time optimizations and reduce compile and link times.
rperl can compile restricted typed syntax, using C++ libraries to operate on typed data and source-level type information. 5-20x better run-time on 5-10% of your code. This is a much better approach then with B::CC, which optimizes only on int and num lexical variables. rperl can also treat efficiently typed and no-magic arrayrefs, hashrefs and function arguments and return types. Because it has control over the parser and compiler, which B::CC has not.
The problem is that rperl cannot use the perl AST, the B optree, because it is too tightly bound to the mostly undocumented internal ops and data, which is hard to work with properly from outside perl5. So rperl uses the PPI AST, interestingly called DOCTREE, does the type optimization and translation to C++ on this doctree via Inline::C++ which is btw. called Inline::CPP, not CXX and has nothing to do with the C preprocessor.
If you look at
rperl/docs/rperl_grammar.txt you'll see the parsed boundaries with which another compiler can interact with
rperl. Basically we could use seperate compilation units (module files
or programs) or single blocks with rperl syntax, and maybe later as advanced
problem subroutines, but then you need to pass the type information of
the arguments and return values back and forth. This is done via
standard XS typemaps.
perlcc and a new script called
buildcc should be usable as
frontend to link seperate compilation units as compiled libraries
(shared or static) together and the different compilers should be
able to detect each other and pass the work back and forth.
It needs to be seperate because they use different parsers and different compilers, but agree on the same types and the typed calling convention. This calling convention should be specified on the C/C++ level, and for the user it would be nice if the perl-level types also agree. The base for these types need to be perl6 types because these are the only ones in existance today.
B::C can do
int and
num and accepts
rperl requires also
object and
void, and can already do
aggregate types, like arrayrefs and hashrefs of those types.
perl6 adds
bool, some more numbers and intermediate and meta
object types, which we dont need yet. What needs to be added are
sized array declarations to be able to omit run-time bounds checks,
but this should be trivial.
rperl already offers compile-time or run-time type-checks and compile-time type optimizations.
p5p and the mop project have no interest in helping with compile-time
optimizations (on type and const information), but there is some minor
progress in getting support for compile-time readonly-ness into
core. My estimation on this is three years, for a simple project which
needs about 2 months work. And actually already exists. It might get
in by adding proper class, role and method support but I would not bet
on it, as the current p5-mop project ignores those possibilities and
even within perl6 I see no focus on OO performance. I see no single
use oo
:closed :final or the accompanying
use class
pragmas yet.
But they implemented the basic type optimizations at least.
How to interface?
Inline is not easy to interface with, notoriously hard to debug, and has several unmaintained bugs and omissions. But it's the best and most transparent way, and the only way to mix perl and rperl code on the source level. The biggest bug is the notorious namespace hack, i.e. the stashes for the generated functions and data are missing. Also argument passing has some serious limitations. Will is using a really crazy hack right now in rperl to push arrayrefs and hashref arguments properly onto the stack. The inline stack macros are too simple, they only work for trivial examples. Inline::CPP does not properly support passing plain arrays and hashes to and from perl5 code, so now rperl uses just scalar types, esp. arrayrefs and hashrefs. We will need to look into lifting those limitations.
Methods and subroutines need to be seperated at compile-time for
rperl/Inline::CPP. In the old days there was a
:method attribute idea,
which is not compile-time accessible, only at run-time. And there were
Devel::Declare based hacks to support class and method keywords, but
they never made it into core. Nowadays
Devel::Declare is not needed
anymore, but there is still no flag to denote methods-only or OO
semantics as in perl6 to enable OO compile-time optimizations, such as
method dispatch and method inlining.
use oo :closed :final. We
cannot even declare yet read-only hashes or
@ISA arrays properly, as
they still clash with restricted hashes and
COW. So they need to be
implemented seperately, as done in rperl. In rperl method types are
done via special type names, to denote the return type and if it's a
method or normal subroutine.
Technically the B::C
-m switch ("compile module") can be easily used
.pm modules alone already, it compiles to a library not to a
standalone. But the problem is to automize the seperation in the code
walker. Any module should only compile itself not its dependencies,
but the parser already included those before the compiler sees it. The
bytecode compiler B::Bytecode already does this seperation by calling
out on the
require op to the other module, and
require observes
.pmc extension, so it loads the other bytecode compiled module.
With B::C the walker and loader is different. The split need to be done
on the FILE field in nextstate CP's, CV's and GV's, it cannot be done on
the current separation, the GV namespaces.
The B::C project timeline is to implement
-m and new its seperation
immediately after the
1.43 release with the target date of fall 2014.
buildcc then collects the deps and drives
perlcc, and
perlcc is used
compiles to modules.
Work started in the
modul branch in the
perl-compiler repo.
-- We, Reini Urban and Will Braswell wrote most parts of this blog post on Saturday January 4, 2014 in Austin in an informal perl11 party celebrating rperl 1.0 beta, with Matt Trout across the street (it was cold and late), but he didn't show up. Maybe he will add some comments later. He supported the idea of an integration somehow.]]>
Shutdown the vm!
$ sudo su -
$ qemu-img resize /var/lib/libvirt/images/windows_x64.qcow2 +5GB
$ modprobe nbd max_part=63
$ qemu-nbd -c /dev/nbd0 /var/lib/libvirt/images/windows_x64.qcow2
$ # fdisk -l /dev/nbd0 # or better
$ ntfsresize --info /dev/nbd0 # to check if the volumes are not dirty
$ gparted /dev/nbd0 # enhance the partition size to max
$ killall qemu-nbd
Start the vm and let windows do the chkdsk /f (in win8 automatically)
ntfsresize -x /dev/nbd0p2 manually
potion, the vm for p2 uses tricky volatile words to force the compiler to put all GC-able data onto the stack, and not in registers so that the GC only needs to walk the stack to find all accessible data. No need to come to tricks like the boem-weiser libgc does to spill registers somewhere to be able to track them. The second trick is to keep the stack properly aligned, at least 16 byte on darwin, but in case of SSE or AVX instructions or with double return values (e.g. atof) the alignment must be 32 byte.
But as is turned out the problem was not related to a missing volatile, which would have caused GC troubles, i.e. SIGBUS errors, nor stack alignment problems (i.e. random data corruption, esp. in the main interpreter).
The first fix was to disable -fstack-protector. I added this to enable all known hardening flags. But stack-protector, esp. -fstack-protector-all corrupted my manual assembly layout.
The second final fix was to add .NOTPARALLEL: test to my Makefile. WTF??
It turned out that all tests work fine if I run them with make -j1 test, but start failing consistently at the same place when using -j2 or -j4. And the cause is my shell-scripted testsuite within the Makefile. When running my for loop for all tests in parallel I got concurrent reads from pipes to extract the expected result from the test via sed.
for f in test/**/*.pl; do \
look=`cat $$f | sed "/\#=>/!d; s/.*\#=> //"`; \
for=`p2 --inspect $$f | sed "s/\n$$//"`; \
if [ "$$look" != "$$for" ]; then \
echo; \
echo "$$f: expected <$$look>, but got <$$for>"; \
failed=`expr $$failed + 1`; \
else \
echo -n .; \
fi; \
count=`expr $$count + 1`; \
done; \
pass=`expr $$pass + 1`
Citing the info page:
"Another problem is that two processes cannot both take input from the same device; so to make sure that only one recipe tries to take input from the terminal at once, make will invalidate the standard input streams of all but one running recipe. This means that attempting to read from standard input will usually be a fatal error (a 'Broken pipe' signal) for most child processes if there are several. It is unpredictable which recipe will have a valid standard input stream (which will come from the terminal, or wherever you redirect the standard input of make). The first recipe run will always get it first, and the first recipe started after that one finishes will get it next, and so on." http://www.gnu.org/software/make/manual/html_node/Parallel.html
Marking the test target with .NOTPARALLEL: test runs the tests not in parallel and all is fine now. Since all 258 tests run in ~1sec I don't care yet to enable parallel testing support.]]>
created by]]>
I found out I never published my game UI, a pretty fast Sudoku solver in native Win32.
After the YAPC::EU in Kiev I first spent some time fixing B::C for 5.16, 5.18 and blead (PADLIST, COW and bytecode compiler regressions). In the meantime my partner in crime goccy in Tokyo made progress with his parser, compiler and the new llvm backend. His parser is hand-written and I'm still fighting with greg, but my code is still much smaller and more elegant.
I spent most of the last days fixing the expression parser and how to parse functions and
method calls. Every expr is a list (TUP for tuple), and calls
can be like
call arg1, args... (implicit list context),
call call args... (nested calls),
call(list) (explicit lists), and similar for methods.
Add indirect method calls to the mix that p2 does only methods, no functions calls. Every call is a method one some object, user-provided subs not in a class (or package) are stored globally and act on the global 'Lobby' object.
expr = c:method { $$ = PN_AST(EXPR, c) }
| c:calllist { $$ = PN_AST(EXPR, c) }
| c:call e:expr { $$ = PN_AST(EXPR, PN_PUSH(PN_S(e,0), PN_S(c,0))); }
| c:call l:listexprs { $$ = PN_SHIFT(PN_S(l,0));
if (!PN_S(l, 0)) { PN_SRC(c)->a[1] = PN_SRC($$); }
$$ = PN_PUSH(PN_TUP($$), c); }
| e:opexpr { $$ = PN_AST(EXPR, PN_TUPIF(e)) }
| c:call { $$ = PN_AST(EXPR, c) }
| e:atom { $$ = PN_AST(EXPR, PN_TUPIF(e)) }
calllist = m:name - list-start - list-end
{ PN_SRC(m)->a[1] = PN_SRC(PN_AST(LIST, PN_NIL)); $$ = PN_TUP(m) }
| m:name - l:list -
{ PN_SRC(m)->a[1] = PN_SRC(l); $$ = PN_TUP(m) }
| m:name - list-start l:callexprs list-end -
{ PN_SRC(m)->a[1] = PN_SRC(PN_AST(LIST, l)); $$ = PN_TUP(m) }
call = m:name - { $$ = PN_TUP(m) }
method = v:methlhs - arrow m:name - l:list -
{ PN_SRC(m)->a[1] = PN_SRC(l); $$ = PN_PUSH(PN_TUPIF(v), m) }
| v:methlhs - arrow m:name -
{ $$ = PN_PUSH(PN_TUPIF(v), m) }
methlhs is a name or $scalar.
The biggest problem was some missing whitespace, and the differences of signature parsing, from the weird potion way, which compiles expr in the compiler to sigs to the new way in p2, where the parser already generates proper signatures.
PN_SHIFT(PN_S(l,0)) orgy above in
call listexprs is for moving the object from the first arg of the call to the front, the indirect method call. I'm not happy with that.
All my perl5 tests pass now, which means there are a lot of new features to explore, like declaring default parameters and calling with named parameters (no need for hash abuse anymore).
$ cat test/closures/named.pl
sub min ($x, $y) { $y - $x }
@b = (99, 98, 97);
$b[1] = "XXX";
(1, min($y=12, $x=89), $b[2], $b[1]) #=> (1, -77, 97, XXX)
$ cat test/closures/default.pl
sub min ($x=0, $y=1) { $y - $x }
(min(), min(1), min(0,1), min($y=0), min, min->arity, min->minargs)
#=> (1, 0, 1, 1, sub($x:=0,$y:=1), 2, 0)
And this is the p2 parse tree
$ bin/p2 -Dv test/closures/default.pl
-- parsed --
code (assign (expr (msg ("min")) expr (proto (list ($x, 58, 0, $y, 58, 1) block (expr (minus (msg ("$y") msg ("$x"))))))), expr (list (expr (msg ("min" list undef undef)), expr (msg ("min" list (expr (value (1))) undef)), expr (msg ("min" list (expr (value (0)), expr (value (1))) undef)), expr (msg ("min" list (assign (expr (msg ("$y")) expr (value (0)))) undef)), expr (msg ("min")), expr (msg ("min"), msg ("arity")), expr (msg ("min"), msg ("minargs")))))
The sig
($x=0, $y=1) is parsed to
($x, 58, 0, $y, 58, 1),
58 being
chr(:). potion uses the
= for type assignment and
:= for defaults, hence
: instead of
=. The 3rd element for each sig, here 0 denotes the default value, which can only be immediate values for now. It could be an expression also, but I dislike the idea. Looks like action at a distance.
Currently all variables and subs are lexical only, work for dynamic symbol lookup is still in a branch. And no example from the shootout benchmark works yet, as I haven't implemented yet for loops, recursive function calls are buggy and similar stuff.
Since the underlying parse tree and vm code is 1:1 the same as for potion, the benchmarks are the same as for potion, i.e. typically 30x faster than perl5 code.]]>
Today I want to smoke whole CPAN in one line to check the new experimental return-or check by Niels Thykier for "Possible precedence issue with control flow", for which we filed several bug reports in the last two days. See https://paste.debian.net/16932/ and perl #59802. To repro add this patch from Niels to latest blead, if it's not already included.
$ cd ~/.cpan
$ alias p='perl5.19.2d-nt@1292fdb2'; alias ppan='AUTOMATED_TESTING=1 PERL_MM_USE_DEFAULT=1 PERL_EXTUTILS_AUTOINSTALL=--defaultdeps p -S cpan'
$ cat allmods.sh
sqlite3 cpandb.sql 'select mod_name from mods group by dist_id order by mod_name;'
$ for m in `./allmods.sh`; do echo $m; ppan -t $m 2>&1 | tee -a log.cpan | grep "Possible precedence issue with control"; done
And in a 2nd term watch it flow, and react on keyboard input.
$ tail -f log.cpan
Note this is just a oneliner, not a real smoker, which needs to setup some environment variables and disable STDIN. For smokers see http://wiki.cpantesters.org/wiki/QuickStart
cpan -t does only testing, but not installing. Major dependencies get built and tested all over again, if they are not installed. This costs some unnecessary minutes. So I added this in a seperate term to keep the most prominent deps.
$ alias jpan='ppan -j ~/.cpan/CPAN/nosqlite.pm'
$ jpan `grep -a "Warning: prerequisite" log.cpan|cut -d' ' -f3|sort |uniq -c|sort -rn|perl -alne'print $F[1] if $F[0] > 5'`'
I need to use a version without use_sqlite to avoid the CPAN::SQLite locking bug. Yes, I've tried to fix it, but some writing codepath still holds a reference to a stmt handle which prevents the readers to be shared.
cd ~/.cpan/CPAN/
sed -e"s,'use_sqlite' => q[1],'use_sqlite' => q[0]," <MyConfig.pm >nosqlite.pm
I filed RT tickets for all found instances and keep the patches in my distroprefs which you can easily
git clone into
WebService-Google-Reader cpan #87211 (fixed)
DBIx-Class-Helpers cpan #87311 (fix in git)
IO-Async cpan #87051 (in work)
YAML-Syck cpan #87034
Done on my desktop machine with 2.8Ghz, 4 cores, 16GB RAM and 15GB free space on my SSD drive. I used 3 cores in parallel, dividing the workload (~26835) by 3. The 4th core for my daytime work. The perl was with DEBUGGING, -g3 and no threads. An optimized perl would have been much faster to run, but would have not detected assertions and would disallow gdb stepping into harder bugs. The only hard bug I found was Data-Alias invalid realloc, so an optimized perl would have been better. At all I needed a week, but it should be doable in 2-3 days with an improved setup. I constantly ran out of disc space after night runs, and rebuilt some popular distros more than 10x. Installing them permanently and checking for discspace would save a lot of time. My distroprefs contains 128 yamls with patches, andy's CPAN prefs contain 449 yamls.
Restarts done like this:
$ wc -l allmods
26835 allmods
$ echo $((26835 / 3))
$ grep -n LastModule mods.1 => 4000
$ for m in `tail -n$((8945-4000)) mods.1`; do echo $m; jpan -t $m 2>&1 | tee -a log.cpan1 | grep "Possible precedence issue with control"; done
See Steffen's Steffen's CPAN explanation and tsee/cpanperlbranch_smoke for smoker setup. He had 25GB and 7 parallel processes on 4 cores.]]>
The last weeks since YAPC I spent most of my p2 time integrating libuv as external "aio" module. This implements asynchronous non-blocking IO and rudimentary cross-platform process support. libuv is essentially the node.js backend library, and MoarVM stated its goal to switch from apr to libuv also.
I needed libuv before the p5 syntax to check the ability to do fast and easy library bindings with lots of callbacks, and without a FFI yet. This gives me now the feeling how the FFI should be implemented, and if the current post-XS API is good enough or lacks some API support from core. As it turned out only some class (=type)/OO features needed to be added to the public potion API, the p2 backend. Everything else went smooth. I also fixed some more core bugs on my way.
I only added a rudimentary testcase, open a TCP connection with a connect callback, nothing realistic so far.
The libuv documentation is here: http://nikhilm.github.io/uvbook/index.html
The p2 aio binding is documented here in the doxygen docs and the htags API reference.
Now I continue where I left off at YAPC, where I added BEGIN block support: The expression parser, method and function calls, and global symbols.]]>
user sromanov found this little limitation and wanted to file a bugreport about it.
Since my vm is hosted on github and github is written in ruby and ruby has the same problem as my app, it turned out as catch-22.
See http://www.fileformat.info/info/unicode/utf8.htm
With 3byte sequences you can represent max 0xFFFF
with 4byte sequences max 0x10FFFF.
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx (3+6+6+6)=21 10FFFF hex (1,114,111)
In my case \x{2603} was representable, but \x{1f42b} not.
perl could of course parse and print \x{1f42b} properly.
We could not file this bugreport, in the first attempts the issue could not be saved without any error message.
Initially I thought this was caused by the recent UI relaunch, so I filed an github support request. I am still waiting for that email being ack'ed.
Then I went to the irc channel #github on freenode, where they asked me to describe my problem further. Apparently they knew nothing about any issues with their issue system.
Good! So I tried to find a syntax problem in my issue report, and partially deleted paragraphs from my text. And after removing the unicode char >0xffff I got the error message: "There was an error posting your comment: Body contains unicode characters above 0xffff"
There was still \x{1f42b} and \u1f42b in the text, but I deleted a 🐫.
I further added spaces after the \x and \u and could save my bugreport.
Then I found others having similar problems, they posted images of their characters, which github could not display.
The stripped down report is at https://github.com/fogus/potion/issues/33
The original report pasted to an app written in perl is at http://paste.perldancer.org/1wxXFG7Z3gluv
I find this extremely disturbing and relevating. If you want to host content on the web, please use a VM and database which supports the basics. I consider utf8 basic nowadays. Why the hell ruby? It's slower than perl, and can do less.
This Socialtext blog SW is written in perl, so it will be able to display those characters, and it will be able to store this blogpost, and it will not silently throw away my blogpost without any error message. So I will not consider theories that the database or the UI folks at socialtext messed up.


text:
Gem Smashers Cheats for GameBoy AdvanceHome / GameBoy Advance /
This page contains Cheats for Gem Smashers organized by sections for GameBoy Advance. Gem Smashers is a Miscellaneous Puzzle General game, made by Frame Studios Interactive, released on Jul 1, 2003 and published by Metro3D. If you can't find a hint or secret in our list, then please check this page periodically for the latest updates.
- Developer:
Gem Smashers GameBoy Advance CheatsFrame Studios Interactive
- Publisher: Metro3D
- Genre: Miscellaneous Puzzle General
- Release Date: Jul 1, 2003
- ESRB: Everyone
Highlight the first selection at the options screen. Press Right(7), Left(7), Right(7). The screen will flash to confirm correct code entry....From: bubblepopfreak
You have to finish story mode as Bau to unlock the first Special Door bonus....From: poke9087
Stuck on this game? Set a specific, clearly defined question and let others answer your question or view answers to previously asked questions. If you think you are an Gem Smashers expert then please try to help others with their questions.
Konjiki No Gashbell!! Yuujou No Dengeki Dream Tag Tournament - Gameplay Video
- Nov 10, 2014, Views: 49
Densetsu No Starfy - Densetsu no Starfy Review Trailer
- May 25, 2014, Views: 251
The Legend Of Stafi - Densetsu no Starfy Review Trailer
- May 25, 2014, Views: 276
Minna No Soft Series: ZOOO - Gameplay Video 1
- May 25, 2014, Views: 272
- ATV: Thunder Ridge Riders - Gameplay Video 1, (GBA)
- Yu-Gi-Oh! Duel Monsters: Beginner Pack 2005 - Gameplay Video 1, (GBA)
- Zooo - Gameplay Video 1, (GBA)
- Super Mario Brothers 3 - YOSHI ISLAND sma3 intro and gameplay (spanish), (GBA)
- Yu-Gi-Oh! GX: Duel Academy - Gameplay, (GBA)
- Zatch Bell! Electric Arena - Gameplay Video 1, (GBA)
- Board Game Classics - (GBA) Gameplay, (GBA)
- Yu-Gi-Oh! 7 Trials To Glory: World Championship Tournament 2005 - Gameplay Video 1, (GBA)
- Kim Kardashian: Hollywood - Gameplay, (iPhone-iPod)
- Episode: Choose Your Story - Gameplay, (iPhone-iPod)
- How To Train Your Dragon 2 - Ready To Fly Trailer, (Wii)
- The Settlers - Kingdoms Of Anteria - Announcement Trailer, (PC)
- Entwined - Quick Look Trailer, (PS3)
- Blue Estate - Official Launch Trailer, (PS4)
- Goat Commando 3D Simulator - Gameplay, (iPhone-iPod)
- Munin - Official Launch Trailer, (iPad)

subset: commoncrawl


text:
- Molded ABS feet with steel insert vinyl
- Durable PVC edge band
- Durable 1" thick top with melamine surface
- Centered modesty panel for guest seating
- Adjustable levelers
- Assembly Required
- Warranty 10 Years
Finish: Slate / White Spectrum
Weight 86 lbs
Furnished Over 1 Million Homes Since 1997...
I was very satisfied with One Way Furniture Service. I have referred them to many friends, family, and customers. Thank you. Kathy A. Eisele, Boston, MA
Product Review - Bush Series A: Slate Peninsula
Furniture Brand
Weight & Size
Reference - Sku: WC8435 - Bush Series A: Slate Peninsula by BBF


text:
10 Steps to Pick the Right Doctor
Whether you need a primary care doctor or a specialist, these 10 steps will ensure you find the right doctor for you. View Slideshow
Dr. Shaheen's Experience
Dr. Shaheen's Care Philosophy
- Phlebology
- Vascular Medicine
- Vascular Surgery
Board Certifications
- General Surgery
- Phlebology
- Vascular Surgery
- Carotid Artery Stent Placement
- Carotid Endarterectomy (CEA) or Excision of Infected Graft
- Dressing and-or Debridement of Wound, Infection, or Burn (incl. Negative Pressure Wound Therapy)
- Embolectomy, Thrombectomy, or Vessel Exploration
- Non-Coronary Angioplasty, Atherectomy, and Stenting
- Peripheral Artery Bypass Procedures
- Peripheral Artery Catheterization
- Thromboendarterectomy or Excision of Infected Graft
- Ultrasound, Carotid
- Varicose Vein Procedures
- Vascular Duplex Ultrasonography and Plethysmography
- Abdominal Aortic Aneurysm (AAA)
- Aortic Aneurysm
- Atherosclerosis of Aorta
- Carotid Artery Disease
- Cerebral Artery Thrombosis
- Cerebral Vascular Disease
- Claudication
- Deep Vein Thrombosis (DVT)
- Familial Venous Malformations
- Fibromuscular Dysplasia
- Gangrenous Disorder
- Lymphedema
- Peripheral Arterial Aneurysm and Dissection
- Peripheral Arterial Disease of Extremities
- Peripheral Arterial Embolism and Thrombosis
- Peripheral Nerve Disorders
- Peripheral Vascular Disease (PAD, PVD)
- Phlebitis and Thrombophlebitis
- Pulmonary Embolism
- Renal Artery Arteriosclerotic Disease
- Restless Leg Syndrome
- Ruptured Aneurysm
- Secondary Hypertension
- Stroke
- Transient Ischemic Attack (TIA)
- Varicose Ulcers
- Varicose Veins
- Vein Diseases
- Venous Embolism and Thrombosis
- Venous Insufficiency
What to Know Before You Go
Background Check for Dr. Shaheen
0 Malpractice Claims
- No malpractice history found for California.
1 Sanction
- Substandard Care, Incompetence or Negligence (5/17/2012)
- Action Taken: Reprimand
- Summary: Please reference the following Document
- Documentation: Download here (PDF)
- State: California
0 Board Actions
- No board actions found for the years that Healthgrades collects data.
Awards & Recognitions
Media & Publications
- Glaxo Wellcome Young Investigator Award, 2000
- The Israel Muss Memorial Award for the medical student who has demonstrated a unique dedication towards research during medical, 1995
- The Norwin Green Award for dedication towards medical research, pursuit of knowledge and humanitarianism, 1996
Education & Training
Medical School
- University Of Louisville School Of Medicine-Magna Cum Laude, Alpha Omega Alpha Honor Medical Society
- Graduated in 1996
Internship Hospital
- Stanford University-General Surgery
- Complete in 1997
Residency Hospital
- Stanford University-General Surgery
- Complete in 2003
Fellowship Hospital
- Northwestern University-Vascular and Endovascular Surgery
- Complete in 2004
Undergraduate Schools
- The University Of California-B. A. Biology (Molecular), Summa Cum Laude
- Graduated in 1991
Other Education
- The National Institues Of Health (N.I.H)-Molecular Biology Research Fellowship
- Complete in 1993
- The University Of Texas M.D. Anderson Cancer Center-Translational Research Fellowship
- Complete in 2000
- University Of Louisville-Hormone Receptor Laboratory Research Fellowship
- Complete in 1992
Languages Spoken by Dr. Shaheen & Staff
- English


text:
Discover Chocolate and Live La Vida Cocoa!
For my chocolate I use cocoa beans from Venezuela, and I would like to try to make chocolate with Ecuadorian cocoa beans. Have you ever tried to roast Ecuadorian cocoa beans? The taste of the raw beans is not acidI think I will try to roast them at low temperatures ( 260F-280F).
What do you think?
Thank you in advance!
© 2014 Created by Clay Gordon.
Badges |
Report an Issue |
Terms of Service
Please check your browser settings or contact your system administrator.


text:
Sigmund's family is invited to uncle Siggy's luau but only if Sigmund is there. But when his brothers try to get him Sigmund he hits his head and thinks he is a little boy.
Jack Wild, the movie star is vacationing on the beach and meet Sigmund and the boys. Sigmund's family take Mr. Wild prisoner, but if you think he'll stand for that…You don't know Jack!
A caveman and his pet dinosaur move into the Ooze's cave and force them out.
When Uncle Siggy finds Sigmund is not at the cave he locates him at the clubhouse - and falls in love with Zelda.
It's Halloween and Sigmund decides to go trick or treating with Johnny and Scott. So Siggy disguises himself as a boy in a sea monster costume.
Sigmund's family evacuates the cave for a storm and Sigmund moves home to avoid Johnny and Scott's parents.
When Sweet Mama kicks Big Daddy out of the cave, he moves into the club house with Sigmund.
Sigmund's mother Sweet Mama decides to redecorate the sea monster cave. But to save money she gets her furniture from Johnny and Scott's house.
Sigmund accidentally breaks Aunt Zelda's bowl and decides to get money from his family's cave to replace it, but he is caught after curfew by the sea monster sheriff.
When Sigmund's brothers find an Ooze brother must attend Ghoul school they try to trick Sigmund into going. Then the boys neglect their schoolwork looking for their sea monster.
Sigmund refuses to sing with his sea monster family in a monster rock concert because he has entered a radio contest looking for new singers!
A Sea Monster tax audit reveals Sigmund is missing. Sigmund's father, facing more taxes sends Sigmund's brothers off to retrieve their little tax deduction. Meanwhile the housekeeper brings her nephew to visit Scott and Johnny.
Zelda the housekeeper plans a birthday party for her friend Sheriff Bevins and depends on the boys to clean the house. But things go wrong when Sigmund cleans the house instead.
When Sigmund gets sick Scott & Johnny find a doctor at the aquarium. But when they realize he only wants him for research they have to cure their sea monster friend themselves.
Sigmund's brothers are frustrated by the fact they cannot recapture Sigmund. Instead they decide to kidnap Scott to do Sigmund's chores. Johnny and Sigmund attempt to rescue him with the help of…Frankenstein???
Download the TV Guide app for iPhone, iPad and Android!


text:
You're leaving Wedding Paper Divas to see the Deal of the Day at our parent site, Tiny Prints.
You won't be able to dismiss this by usual means (escape or click button), but you can close it programatically based on user choices or actions.
"The quality of the paper and printing was excellent. We also wanted the postcard style, but with nothing on the back, and there was no confusion with them. They did exactly what we asked, and sent us a proof so quickly. Definitely ordering our invitations through them!"
"I love this design! Being able to have the At Last with the photo option is exactly what we wanted to send to family after a long engagement! Perfect!!"
"I loved being able to add my own artwork to the cards and customizing everything down tonthe front style, size, color everything! The template was a guide that allowed me free range to transform my save the dates into one of a kind. My designer was able to accommodate all my requests in an INCREDIBLY timely manner. The quality and stock of the paper was impressive as well as the printing. The colors match how it was translated on the computer. It was identical to my proofs, and arrived within the same week I placed the order! I couldn't be more satisfied with the products or the incredible service I recieved from those who helped during the process."
"The save the dates look fantastic. It was easy to work with Wedding Divas' designers to make sure everything was perfect and fit in all the information we wanted on the card. The quality of the paper is great and the photo printed out really clear. I'm excited to send them out!"
"we needed a simple yet a beautiful design that would stand out with our outrageous photo. We could not have done any better. This design was perfect!! The magnets are the perfect size and not too heavy. Other magnets I have seen are WAY to large."


text:
Jennifer Lopez is Pregnant
you might also enjoy the one with the lobster.
(Lola means grandmother in Tagalog.)
7th Heaven returns at the expense of EVERWOOD?! My life is over…
Yay for Lola!
haha j@red, I actually saw this on myspace some time ago. Kudos to you for posting it here. Goooo LoLa!!!!! poor crab lmao
Thanks Jared for embracing part of my culture. "Mabuhay ang Pilipinas."Salamat.
haha oh lola. gahh that was just SO filipino.
lola is so funny!…proud 2 b noypi!
The CW should realise whats best for them and put Milo Ventimiglia (Jess in Gimore Girls, Richard in Bedford Diaries), in every program going Especially Gilmore Girls , he is so intensely hot and brooding , plus portrays Jess as such a mulitfaceted vulnerable bad boyThey should get Rory to dump rch spoilt frat boy Logan, for her true soul mate – and partner in real life
When you look at those pics of Tyra Banks close-up, she has quite a mustache.
Whoa! Just some observations, high rez is Soooo harsh. Obviously these are all lovely girls.1) Kristin Kreuk has a thick nose hair! haha. Otherwise flawless.2) Did Erica Durance get a nose job recently? 3) Tyra!! You've hidden the hairline problem, but oh man!!! The MOUSTACHE. So full!!!!!


text:
What are your comments?
Join the discussion today. Login Here.
...as I pointed out on the SCADA list, what was so secure or reliable about using people to read meters? The same concerns apply here.
No one has commented on this page yet.
RSS feed for comments on this page | RSS feed for all comments


text:
Stream, River in Harrison County, Mississippi, USA.
Latitude: 30.42028 : Longitude: -88.97944
Blogs and Websites Near Biloxi River, Mississippi - GeoURL
Biloxi River Map - Multimap
Biloxi River Street Map and Satellite Photo - Google Maps
Biloxi River Aerial Photo and Topo Map - Terraserver
Biloxi River Map - MSN
Environmental Hazards, Flood Area Maps, Boundaries - EPA
Biloxi River Area Map - MapQuest
Weather Forecast near Biloxi River - Multimap
The weather forecast links don't work for all places yet.
Some random places: Faude Park Puck Fountain Opdyke Thodab Claim PCM Community School


text:
Advertisement:Close [X]
100% via 6 votes6
Lesbian Pleasure Bunny having sex with her girlfriend on the couch
- 21,890
- October 12, 2011
Foxy Black Butts Bring on them hot black asses!! An array of sexy black apple butts on parade just for you!! and just to make it even better - they are ready for a good old fashion fucking!! Whoop! There is a god!
Related content
Twitter follow @porntube
From Our Blog Blog RSS
We are happy to help.
Choose your size


text:
The Rawtarian Blog
FREE Raw Recipe Package
Subscribe to newsletter below. Get the 11 Best Raw Recipes (PDF E-Book Package) instantly.
The Rawtarian Recipes
- Raw Dessert Recipes
- Smoothie, Juice And Breakfast Recipes
- Raw Savory Recipes
- Raw-Nut-Free Recipes
- Raw Dehydrator Recipes
Latest Certifications
CharmaineRaw Food Diet Plan (Full course)December 8, 2014
vogeljerRaw Food A to ZDecember 8, 2014
ElsaRaw Food Diet Plan (Full course)December 6, 2014


text:
free shippingon most orders over $49*
Get 3% Backwith AllModern rewards
Hitchcock Butterfield Company Textured Black & Copper Framed Wall Mirror
30" W x 40" H Size
33" W x 45" H Size
33" W x 69" H Size
39" W x 49" H Size
39" W x 78" H Size
45" W x 57" H Size
57" W x 84" H Size
Hitchcock Butterfield Company Textured Black & Copper Framed Wall Mirror
Weights & Dimensions
30" W x 40" H Size
33" W x 45" H Size
33" W x 69" H Size
39" W x 49" H Size
39" W x 78" H Size
45" W x 57" H Size
57" W x 84" H Size
Additional Weights & Dimensions
|Mirror Type: Wall mirror
|Frame Shape: Rectangle
|Hanging Orientation: Both
|Style: Traditional
|Frame Finish: Black and copper
|Hardware Finish: Stainless steel
|Distressed: No
|Frame Material: Plastic
|Hardware Material: Stainless steel
|Number of Items Included: 1
|Rust Resistant: Yes
|Corrosion Resistant: Yes
|Fade Resistant: Yes
|Tarnish Resistant: Yes
|Jewelry Storage Included: No
|Shelves Included: No
|Drawers Included: No
|Hooks Included: No
|Stemware Storage Included: No
|Swing Arm Included: No
|Lighted: No
|Beveled Glass: Yes
|Tilt Mirror: No
|Commercial Use: Yes
|Eco-Friendly: Yes
|Country of Manufacture: United States
|Assembly Required: No
|Installation Required: Yes
|Additional Parts Required: No
|Product Warranty: 1 Year
|ADA Compliant: No
|ASTM Compliant: Yes
|CPSIA or CPSC Compliant: Yes
|Damp, Dry or Wet Location Listed: Dry
|EPA/CPG Compliant: Yes
Still have questions about this product? We're here to help
Hitchcock Butterfield Company Textured Black & Copper Framed Wall Mirror
|5 star
|4 star
|3 star
|2 star
|1 star
Tell Us What You Think!
Tell us what you think about the Textured Black & Copper Framed Wall Mirror. It will help us provide you with better products in the future and help your fellow Wayfair shoppers make better purchases.Write A Review
Looks cheap
Dinny from Chicago, IL
I was surprised when I received this. Thought it would look like a wood mirror as it said "woodcraft" doesn't look like wood at all. Saw the same mirror at JC Penney for $60.00. Great mirror for $60.00.
I will buy this product again
JDE8348 from Boca Raton FL– Verified Buyer
I purchase mirrors for new offices that I build in the personal service industry and this has by far been the best look, quality, and style that I've used. I will continue to use them going forward.
Beautiful accent piece
Simply Cyndi from Boca Raton, FL
This beautiful mirror coordinates with our Tuscan design perfectly! It's just a stunning match!!
About the ManufacturerThe Hitchcock-Butterfield mirror company is part of a family of families. 47 year old business of products made in America. Featured on Ellen DeGeneres, Dianne Sawyer, Barbara Walters', and on a local CBS news cast interview. Their future is most promising selling into Canada, parts of Europe, South America and all 50 states. They design new mirror products and produce custom orders. Architects, decorators, designers contact them daily because they are made in America. All mirrors are made fresh in St. Louis, MO. with quality materials and workmanship.
OUR SKU # IY2047Textured Black & Copper Framed Wall Mirror is also sometimes listed under the following manufacturer numbers: 202000, 202002, 202003, 202004, 202007, 202008, 202009


text:
What does NE mean in Physiology?
This page is about the meanings of the acronym/abbreviation/shorthand NE in the Medical field in general and in the Physiology terminology in particular.
Neurological Equivalent
Find a translation for NE in other languages:
Select another language:
What does NE mean?
- Nebraska.
Discuss this NE abbreviation with the community:
Use the citation below to add this abbreviation to your bibliography:
"NE." Abbreviations.com. STANDS4 LLC, 2014. Web. 20 Dec. 2014. <http://www.abbreviations.com/term/122860>.
NE also stands for:
... and 92 more »
Nearby & related abbreviations:
Alternative search:
- Search Neurological Equivalent on Amazon.com
- Search Neurological Equivalent on Google


text:
|Hi there,
so I am in the process of dealing with a slight virus problem, several Dahlias with slightly mottled leaves.
I came across epsom salt (Magnesium sulphate) as additional feed.
My Dahlias are in the soil, and I intended to spray the foliage.
BUT,.... I a not sure what strenght to use.
- 1 teaspoon per gallon, to use on container Dahlias, that would be probably 0,13% (if I did the math right)
-in the internet I found varying recommendation, mainly for agricultural crops for spraying the foliage, ranging from 2% to 5% (for wheat, asparagus, cabbage etc).
so, I thought to go for a 1%-solution or 0.5% and spray it once.
And just for curiosity`s sake I would water one row (out of three) with a stronger solution).
Any comments or hints concerning the dosage?
And how long should it take to show a response (1-2 days or a week)?
Well, thanks for your thoughts, bye, Lin
Follow-Up Postings:
- Posted by CCvacation none (My Page) on Wed, Aug 28, 13 at 13:47
|Lin, I have heard varying amounts, as well. After comparing different recommended amounts, I ended up both foliar-feeding and applying to the soil directly at different times.
With Foliar feed, I used two tablespoons dissolved in a cup of hot water, and added to a two- gallon sprayer.
On several separate occasions, I sprinkled 1-2 tablespoons directly to the top of the soil around each stalk and tuber.
Every method showed better-looking leaves in about ten days. Many plants that showed virus sign ended up looking great, while a few didn't seem to improve. Those need pulled.
Please Note: Only registered members are able to post messages to this forum. If you are a member, please log in. If you aren't yet a member, join now!
If you are a member, please log in.
If you aren't yet a member, join now!
Return to the Dahlia Forum
Information about Posting
- You must be logged in to post a message. Once you are logged in, a posting window will appear at the bottom of the messages. If you are not a member, please register for an account.
- Please review our Rules of Play before posting.
- Posting is a two-step process. Once you have composed your message, you will be taken to the preview page. You will then have a chance to review your post, make changes and upload photos.
- After posting your message, you may need to refresh the forum page in order to see it.
- Before posting copyrighted material, please read about Copyright and Fair Use.
- We have a strict no-advertising policy!
- If you would like to practice posting or uploading photos, please visit our Test forum.
- If you need assistance, please Contact Us and we will be happy to help.
Learn more about in-text links on this page here


text: It is a useful device for certain occasions, easily integrable with any mobile device. Besides being extensible, is easily separable delcable linking it to your mobile device, as it is the cable that connects the cap that hides the touch pointer. Depending on the device, not easily detected. Works great ... Read more


text:
Gamma - A unit of measurement of magnetic intensity.
Geiger Counter - An instrument used in the search for radioactive minerals, particulary uranium, as it is capable of detecting (by means of a Geiger Mueller tube) the rays emanating from such minerals. It registers the frequency or intensity of these rays either visually (by dial or flashing light), audibly (by earphones) or both.
Geology - The science concerned with the study of rocks making up the earth.
Gold - A precious yellow metallic element, highly malleable and ductile, and not subject to oxidation or corrosion. Symbol: Au; atomic weight: 196.967; atomic number: 79
Greenhorn – A novice or inexperienced miner – usually given the least desirable jobs in the mining camp.
Guides - The timber along the sides of a shaft for the purpose of steadying, or guiding, the cage or conveyance.
Hanging Wall - The wall or rock on the upper or top-side of a vein or ore deposit.
Heading - A vein above a drift. An interior level or airway driven in a mine.
Highgrade - Rich ore – high in mineral content. 'Highgrade' used as a verb means the selectively mining the best ore in a deposit.
Highgraded - One who steals rich ore, especially gold, from a mine.
Host Rock - The rock containing an ore deposit.
Hydraulic - This describes a common method of mining in which water under pressure is used to cut away banks of gold-bearing gravels or overburden. Water is brought to the operation from a "head"; the water is then discharged into a pipeline, at the end of which is a nozzle called a "monitor" or a "giant".
Jackleg – A percussion drill mounted on a telescopic leg. The leg and the machine are hinged so the drill can point in the opposite direction. A hard tool to get the hang of – it works using a combination of drilling and water and is an essential tool in mining.
Jig - An apparatus used in milling to concentrate ore on a screen submerged in water, either by a reciprocating motion of the screen or by the pulsation of water through it.
Lagging - Planks or small timbers placed along the roof of a stope or drift to prevent rocks from falling, rather than to support the main weight of the overlying rocks.
Lamp - The electric cap lamp worn for visibility. Also, the flame safety lamp used in coal mines to detect methane gas concentrations and oxygen deficiency.
Lode - A mineral deposit in solid rock.
Loop – Glass magnifier used to determine rough mineral content.
Sometimes what seems easy is actually hardness in disguise as Ty renounces his God spirit and becomes mortal.
Its Loki to the rescue as Mike narrowly escapes being killed by a crossbow-wielding, scripture-quoting God hunter.
Starting January 15, Smackdown moves to Thursdays at 8/7c.


text:
Trip Europa
Have a safe trip and I hope it's packed with fun adventures. Did you know Augustus Gloop in Charlie and the Chocolate Factory is from Düsseldorf?
I'm excited for more travel news. :)
Ready, set, GO!
Trip Start Jun 04, 2008
11Trip End Jun 24, 2008
Map your own trip!
Loading Map
Loading Map
Map Options
Show trip route
Hide lines
We decided to try to stay up late so we'll be able to sleep on the plane and avoid the jet lag. Who knows whether this will work or not, but we can sure try! Another reason for us staying up is to see the Vorans when they return from Columbia at 11.
We talked to Kevin today. He's already at Amelies and will go to school with her tomorrow, which is probably actually right now. This whole time change thing is going to be confusing.
The plan is to leave Newton around 8 am. We'll take off from Wichita at 10:40 for Atlanta. We leave Atlanta at 4:30ish and then arrive in Dusseldorf at 7:40 am local time. That's about 12:40 Kansas time. So if we get any sleep at all it will be between 4 and midnight. Good times.
Thank you all for your warm wishes. We're ready to have fun!
Trip Europa
bon voyage!
Hope you guys are having fun! Heard that you are traveling with the local Wichita sportscasters to Florida. Maybe you'll meet some real celebs in Europe. Be sure to tell Amelie and her family 'Hi' for me. Take care and bring back lots of chocolate and pics to share. Love, Aunt B.


text:
Crude oil price head higher today, currently traded at USD107.23 per barrel in futures trading and are likely to head higher given the unfolding unrest in the Middle East and post-quake reconstruction in Japan.
Since the price already break USD106 on last night, it may target 300% fibonacci level at USD109.73
Hmm.. will our Ron 95 and Ron 97 also increase as well? Yes, I heard a rumor that RON 97 price will increase tonight effective on 2 April 2011. But still I did not receive any confirmation of that rumor. If this rumor is correct, then the new price for Ron 97 will be RM2.70 per litre.
Update: Confirmed, increased by RM0.20 so the new price will be RM2.70. The highest in two year. Ron 95 remains unchanged (at this moment).
What's behind the oil spike? Read here.
- 5 perkara paling mengarut yg anda tak nak tengok
- Hyderabad - bandar lama yg wajib anda lawati
- Melancong percuma ke negara yg popular ni!
- Pernah anda tengok cookie monster?
- Mudahkan hidup anda dengan ketahui teknik ini
- Hanya ibu bapa sahaja akan faham seronoknya hal ini
- Baca ni jika anda pengguna Estee Lauder
- Melancong percuma jika anda ada ASTRO
- Melancong ke Filipina percuma?
- Comel melampau-lampau budak ni


text:
'Muslins are often expensive but these were very good value'
Mel - Skipton
'I brought this for use at home and i'm glad i did. The antibacterial film 'cartridges' that go in this...'
Dennys Mum - Peterborough
'I truly wish that I had one of these products with My two older daughters.'
Steveo Highton - Runcorn
'The Quilted Anti Allergy Mattress Protector is a luxurious, padded, quilted protector for a comfortable...'
Kiddicare Staff Expert - Peterborough
'I bought these as I wanted to use reusables as they are cheeper and I also wanted to help the environment....'
Lukes Mum - Coventry
'The just4bums Maxi Plus Disposable Nappies (Size 4+)'
Kiddicare Staff Expert - Peterborough


text:
Daily Inspiration #33
Posted by 7Shadows • 1459 Views • 35 Replies • FacebookTwitter
Posted by 7Shadows • 1459 Views • 35 Replies • FacebookTwitter
Today's daily inspiration is a selection of very talented artists. Each piece that we've selected is here to help inspire you! We hope you are inpired to create and to enjoy the glory of our selected artwork! If you wish to suggest an artwork that inspires YOU, reply to this topic, or to our updates on http://fb.com/shadowness, or via Twitter to http://twitter.com/shadowness9
We'd also like to draw your attention to the new Shadowness For the Win contest! We're giving away $1,500 in cash and prizes! You can find out more at: http://www.shadowness.com/forthewin
Thanks for sharing your awesome works. Congrats guys! ♥Apr 9th, 2011
awesomeness :DApr 9th, 2011
wow very nice selection! Congrats to all the artists.Apr 9th, 2011
Thank you so much for the feature! I appreciated it a lot. :)Apr 9th, 2011
So many great features, thank you again!Apr 9th, 2011
Great feature! Thanks so much for including my photo!Apr 9th, 2011
thanks a lot you have to enter my work in here :).....Apr 9th, 2011
wow...my first post featured here...
thanks for the Shadowness...!!!
thankyou for featuring my work :)Apr 9th, 2011
awesome...so many!!Apr 10th, 2011
thanks for featuring that old thingApr 10th, 2011
kamsia kamsiaApr 10th, 2011
I'm inspired nowApr 10th, 2011
Thank you so much for the honor.Apr 10th, 2011
wonderful selection :) just took a bunch of them home with me to favs+comments =P +follows!Apr 10th, 2011
great collection, thanks you Shadowness!Apr 10th, 2011
Thanks for the Feature on my Pug Dog!!Apr 10th, 2011
Thanks for featuring my work guys, so pleased to be in Daily Inspiration. Some great pieces here.Apr 10th, 2011
Tanks for the FeatureApr 10th, 2011
thanks for the featureApr 10th, 2011
Thank you kindlyf or the feature :))Apr 10th, 2011
Great works in here. :)Apr 10th, 2011
I feel inspired :DApr 10th, 2011
thank you so much for featuring my work in this amazing selection.Apr 10th, 2011
great work..
lov it..
nice one...Apr 10th, 2011
Thank you for the feature! So many awesome works here.. LOVE it !!Apr 10th, 2011