Purpose
A slightly uncommon bit-twiddling operation is "popcount", which counts the number high bits. While uncommon, it's crucial for implementing Array Mapped Tries, which is a way to implement immutable maps and vectors. I'm trying to implement immutable maps and vectors, so I needed to implement popcount.I found A TON of ways, but had no idea which was fastest. So, I implemented them all and tested them. The short answer is to do this:
#http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable POPCOUNT_TABLE16 = [0] * 2**16 for index in xrange(len(POPCOUNT_TABLE16)): POPCOUNT_TABLE16[index] = (index & 1) + POPCOUNT_TABLE16[index >> 1] def popcount32_table16(v): return (POPCOUNT_TABLE16[ v & 0xffff] + POPCOUNT_TABLE16[(v >> 16) & 0xffff])And here's the long answer:
Results
I ran popcount on 30,000 random ints between 0 and 2
Name | Time | Max Bits | URL |
c_bagwell | 0.0030 | 32 | http://lamp.epfl.ch/papers/idealhashtrees.pdf |
c_bsdmacro | 0.0030 | 32 | http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html |
c_parallel | 0.0031 | 32 | http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel |
c_ops64 | 0.0036 | 32 | http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSet64 |
table16 | 0.0098 | 32 | http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable |
c_table8 | 0.0110 | 32 | http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaive |
table+kern | 0.0132 | - | http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable |
table8 | 0.0163 | 32 | http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable |
bsdmacro | 0.0190 | 32 | http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html |
parallel | 0.0199 | 32 | http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html |
ops64 | 0.0207 | 32 | http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSet64 |
bagwell | 0.0242 | 32 | http://lamp.epfl.ch/papers/idealhashtrees.pdf |
freebsd | 0.0257 | 32 | http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html |
timpeters3 | 0.0277 | 32 | http://mail.python.org/pipermail/python-list/1999-July/007696.html |
timpeters2 | 0.0580 | 32 | http://mail.python.org/pipermail/python-list/1999-July/007696.html |
timpeters | 0.0724 | ? | http://mail.python.org/pipermail/python-list/1999-July/007696.html |
kernighan | 0.0745 | - | http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan |
elklund | 0.0889 | - | http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html |
naive | 0.1519 | - | http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaive |
seistrup | 0.2447 | ? | http://mail.python.org/pipermail/python-list/1999-July/007696.html |
And here are the results for my MacBook with a 2.0Ghz Core 2 Duo:
Name | Time | Max Bits | URL |
table16 | 0.0279 | 32 | http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable |
table+kern | 0.0372 | - | http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable |
table8 | 0.0417 | 32 | http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable |
bsdmacro | 0.0481 | 32 | http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html |
bagwell | 0.0596 | 32 | http://lamp.epfl.ch/papers/idealhashtrees.pdf |
timpeters3 | 0.0744 | 32 | http://mail.python.org/pipermail/python-list/1999-July/007696.html |
parallel | 0.0807 | 32 | http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html |
ops64 | 0.1290 | 32 | http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSet64 |
timpeters2 | 0.1439 | 32 | http://mail.python.org/pipermail/python-list/1999-July/007696.html |
kernighan | 0.1527 | - | http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan |
timpeters | 0.1668 | ? | http://mail.python.org/pipermail/python-list/1999-July/007696.html |
freebsd | 0.1772 | - | http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html |
elklund | 0.1913 | - | http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html |
naive | 0.2889 | - | http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaive |
seistrup | 0.6106 | ? | http://mail.python.org/pipermail/python-list/1999-July/007696.html |
Observations
- Implementations written in C (using Pyrex) are 5-6 times faster than Python.
- My 3.2 Ghz Linux Desktop is 200% faster than my 2.0 Ghz MacBook even though it only has a 60% clockspeed advantage. I'm not sure what to make of that. Python doesn't use multiple cores well, so I'm sure it's not that.
- If you want to run popcount on 32-bit values in pure Python, table16 is the fastest by far, and only 3 times slower than implementations in C.
- If you need to run popcount on arbitrarily large integers, kernighan is the best, but doing a hybrid of table16 and kernighan is probably better.
Conclusion
If you don't mind using about 64KB of memory, here's is the fastest popcount in pure python:#http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable POPCOUNT_TABLE16 = [0] * 2**16 for index in xrange(len(POPCOUNT_TABLE16)): POPCOUNT_TABLE16[index] = (index & 1) + POPCOUNT_TABLE16[index >> 1] def popcount32_table16(v): return (POPCOUNT_TABLE16[ v & 0xffff] + POPCOUNT_TABLE16[(v >> 16) & 0xffff])If you do mind the memory usage, here's a slighly slower version:
#http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable POPCOUNT_TABLE8 = [0] * 2**8 for index in xrange(len(POPCOUNT_TABLE8)): POPCOUNT_TABLE8[index] = (index & 1) + POPCOUNT_TABLE8[index >> 1] def popcount32_table8(v): return (POPCOUNT_TABLE8[ v & 0xff] + POPCOUNT_TABLE8[(v >> 8) & 0xff] + POPCOUNT_TABLE8[(v >> 16) & 0xff] + POPCOUNT_TABLE8[ v >> 24 ])And if you need to handle values of more than 32 bits, one of these two are the best:
#http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan def popcount_kernighan(v): c = 0 while v: v &= v - 1 c += 1 return c POPCOUNT32_LIMIT = 2**32-1 POPCOUNT_TABLE8 = [0] * 2**8 for index in xrange(len(POPCOUNT_TABLE8)): POPCOUNT_TABLE8[index] = (index & 1) + POPCOUNT_TABLE8[index >> 1] def popcount_hybrid(v): if v <= POPCOUNT32_LIMIT: return (POPCOUNT_TABLE16[ v & 0xffff] + POPCOUNT_TABLE16[(v >> 16) & 0xffff]) else: c = 0 while v: v &= v - 1 c += 1 return cIf it needs to be faster than that, write in C!
Test For Yourself
If you want to test these yourself, here's some code you can run.#http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaive def popcount_naive(v): c = 0 while v: c += (v & 1) v >>= 1 return c #http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan def popcount_kernighan(v): c = 0 while v: v &= v - 1 c += 1 return c #http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable POPCOUNT_TABLE8 = [0] * 2**8 for index in xrange(len(POPCOUNT_TABLE8)): POPCOUNT_TABLE8[index] = (index & 1) + POPCOUNT_TABLE8[index >> 1] def popcount32_table8(v): return (POPCOUNT_TABLE8[ v & 0xff] + POPCOUNT_TABLE8[(v >> 8) & 0xff] + POPCOUNT_TABLE8[(v >> 16) & 0xff] + POPCOUNT_TABLE8[ v >> 24 ]) POPCOUNT_TABLE16 = [0] * 2**16 for index in xrange(len(POPCOUNT_TABLE16)): POPCOUNT_TABLE16[index] = (index & 1) + POPCOUNT_TABLE16[index >> 1] def popcount32_table16(v): return (POPCOUNT_TABLE16[ v & 0xffff] + POPCOUNT_TABLE16[(v >> 16) & 0xffff]) POPCOUNT32_LIMIT = 2**32-1 def popcount_table16_kernighan(v): if v <= POPCOUNT32_LIMIT: return (POPCOUNT_TABLE16[ v & 0xffff] + POPCOUNT_TABLE16[(v >> 16) & 0xffff]) else: c = 0 while v: v &= v - 1 c += 1 return c #http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSet64 def popcount32_ops64(v): return ((((v & 0xfff) * 0x1001001001001 & 0x84210842108421) % 0x1f) + ((((v & 0xfff000) >> 12) * 0x1001001001001 & 0x84210842108421) % 0x1f) + (((v >> 24) * 0x1001001001001 & 0x84210842108421) % 0x1f)) #http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel #also http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html def popcount32_parallel(v): v = v - ((v >> 1) & 0x55555555) v = (v & 0x33333333) + ((v >> 2) & 0x33333333) #v = (v & 0x0F0F0F0F) + ((v >> 4) & 0x0F0F0F0F) #v = v + ((v >> 4) & 0x0F0F0F0F) v = (v + (v >> 4)) & 0x0F0F0F0F v = (v * 0x1010101) >> 24 return v % 256 #I added %256. I'm not sure why it's needed. It's probably because of signed ints in Python def popcount32_bagwell(v): v = v - ((v >> 1) & 0x55555555) v = (v & 0x33333333) + ((v >> 2) & 0x33333333) v = (v & 0x0F0F0F0F) + ((v >> 4) & 0x0F0F0F0F) v = v + (v >> 8) v = (v + (v >> 16)) & 0x3F return v #http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html def popcount_elklund(v): c = 0 while v: v ^= v & -v c += 1 return c #http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html def popcount32_freebsd(v): v = (v & 0x55555555) + ((v & 0xaaaaaaaa) >> 1); v = (v & 0x33333333) + ((v & 0xcccccccc) >> 2); v = (v & 0x0f0f0f0f) + ((v & 0xf0f0f0f0) >> 4); v = (v & 0x00ff00ff) + ((v & 0xff00ff00) >> 8); v = (v & 0x0000ffff) + ((v & 0xffff0000) >> 16); return v #http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html def popcount32_bsdmacro(v): #define BITCOUNT(x) (((BX_(x)+(BX_(x)>>4)) & 0x0F0F0F0F) % 255) #define BX_(x) ((x) - (((x)>>1)&) - (((x)>>2)&0x33333333) - (((x)>>3)&0x11111111)) # #def bx(v): (v - ((v >> 1) & 0x77777777) - ((v >> 2) & 0x33333333) - ((v >> 3) & 0x11111111)) #def bc(v): ((bx(v) + (bx(v) >> 4)) & 0x0F0F0F0F) % 255 v = (v - ((v >> 1) & 0x77777777) - ((v >> 2) & 0x33333333) - ((v >> 3) & 0x11111111)) v = ((v + (v >> 4)) & 0x0F0F0F0F) return v % 255 #http://mail.python.org/pipermail/python-list/1999-July/007696.html import marshal, array, struct, string POPCOUNT8_TRANS_TABLE = "".join(map(chr, POPCOUNT_TABLE8)) #changed by me to match new dumps() and use sum() def popcount_timpeters(v): counts = array.array("B", string.translate(marshal.dumps(v), POPCOUNT8_TRANS_TABLE)) # overwrite type code counts[0] = 0 return sum(counts) #changed by me to add loop unrolling and not setting digitcounts[0] def popcount32_timpeters2(v): counts = array.array("B", string.translate(marshal.dumps(v), POPCOUNT8_TRANS_TABLE)) return counts[1] + counts[2] + counts[3] + counts[4] #improved by me: no need to translate type char def popcount32_timpeters3(v): dumped = marshal.dumps(v) return POPCOUNT_TABLE8[ord(dumped[1])] + POPCOUNT_TABLE8[ord(dumped[2])] + POPCOUNT_TABLE8[ord(dumped[3])] + POPCOUNT_TABLE8[ord(dumped[4])] #http://mail.python.org/pipermail/python-list/1999-July/007696.html _run2mask = {1: 0x5555555555555555L, 2: 0x3333333333333333L, 4: 0x0F0F0F0F0F0F0F0FL, 8: 0x00FF00FF00FF00FFL} def buildmask2(run, n): run2 = run + run k = (n + run2 - 1) / run2 n = k * run2 try: answer = _run2mask[run] k2 = 64 / run2 except KeyError: answer = (1L << run) - 1 k2 = 1 while k > k2: k2 = k2 + k2 if k >= k2: answer = answer | (answer << (run * k2)) else: answer = answer | (answer << (run2 * (k - k2/2))) k2 = k if k2 > k: answer = answer >> (run2 * (k2 - k)) return answer, n def nbits(v): return 32 #??? def popcount_seistrup(v): lomask, n = buildmask2(1, nbits(v)) v = v - ((v >> 1) & lomask) target = 2 while n > target: lomask, n = buildmask2(target, n) v = (v & lomask) + ((v >> target) & lomask) target = target + target for i in range(1, target/2): if n <= target: break n = n >> 1 n = (n + target - 1) / target * target v = (v & ((1L <<>> n) return int(v) if __name__ == "__main__": import time, random def time_func(func): before = time.time() result = func() after = time.time() span = after - before return result, span popcounts = [popcount_naive, popcount32_table8, popcount32_table16, popcount_table16_kernighan, popcount_kernighan, popcount32_ops64, popcount32_parallel, popcount32_bagwell, popcount_elklund, popcount32_freebsd, popcount32_bsdmacro, popcount_seistrup, popcount_timpeters, popcount32_timpeters2, popcount32_timpeters3, ] test_count = 30000 max_int = 2**31 - 2 ints = range(0, 257) + [random.randint(0, max_int) for _ in xrange(test_count)] + range(max_int - 100, max_int+1) expected_counts = map(popcount_naive, ints) for popcount in popcounts: counts, timespan = time_func(lambda : map(popcount, ints)) print "%5.5f %s" % ((timespan if (counts == expected_counts) else -1), popcount.__name__) #-1 means failure
In python 3 I've found (to my disappointment) that a simple bin(num).count('1') is faster than the table16 algorithm you've posted. As I was trying to replace the gmpy version of popcount I was using, this was not good enough. Thankfully, I was interested in a special case of the problem, namely I was doing a test for
ReplyDeletepopcount(a) > 1
so, inspired by the posted algorithm, I was able to replace that with:
a not in onebit
where onebit is a tuple constructed as follows:
onebit = [0]
for i in range(32): onebit.append(2**i)
onebit = tuple(onebit)
another benefit is that you get to set the size you are interested in just by changing the range of the loop. (in my case, 17 was sufficient.
Interesting results, thanks for compiling this.
ReplyDeleteOne option that has been over-looked, perhaps, is an 11-bit look-up table:
POPCOUNT_TABLE11 = [0] * (1 << 11)
for index in xrange(len(POPCOUNT_TABLE11)):
POPCOUNT_TABLE11[index] = (index & 1) + POPCOUNT_TABLE11[index >> 1]
def popcount32_table11(v):
return (POPCOUNT_TABLE11[ v & 0x7ff] +
POPCOUNT_TABLE11[(v >> 11) & 0x7ff] +
POPCOUNT_TABLE11[ v >> 22 ])
This actually runs the fastest on my system, I imagine due to caching better than the 16-bit table, being 32x smaller.
The problem is that your benchmarks assume your aren't doing anything OTHER than popcount. On newer x86 processors, the 64K table will fit in (and fill) the L1 data cache, making it very fast, but only as long as it can hog the entire L1 cache! In real code, you'll likely be doing other things that require L1 cache as well, so this will run effectively 3x slower (L2 cache speed)...
ReplyDeleteخدمات النظافة بالدمام لابد ان تقدمها شركة لديها ثقة في اتمام خدمات النظافة المنزلية لان النظافة العاية لا تعطي النتيجة الفعالة التي تتم بواسطة شركة تنظيف بالدمام متخصصة لانها تهتم بكل شئ داخل المباني فلدينا شركة تنظيف فلل بالدمام تكون متخصصة في نظافة الفلل المفروشة والمستعملة واعطائها الرونق الجمالي الخاص بها لدينا شركة تنظيف شقق بالدمام متخصصة في اعمال نظافة الشقق المنزلية وشقق المكاتب والمعارض بواسطة الادوات والمواد اللازمة لعمل ذلك لدينا تخصصتنا في اعمالنا التي ترضي العميل وتخلصة من الحشرات الصغيرة التي تسبب ازعاج كبير للاسرة من خلال شركة مكافحة حشرات بالدمام التي لديها معدتها وموادها لعمل ذلك كما يوجد متخصص ايضا للقضاء علي الحشرات من خلال التواصل مع شركة رش مبيدات بالدمام التي تنتهيك من كل الحشرات المنزلية كما نعمل معا للواصل اليك كل الخدمات المنزلية من خلال خدمة الاثاث بواسطة افضل شركة نقل اثاث بالدمام والتعامل معها سوف يصل الي منزلك الجيد بدون اي تعب
ReplyDeleteكما يوجد خدمتنا الاخري التي يمكنك البحث عنها م والاستفادة منها
شركة تنظيف بالقطيف
شركة تنظيف بالجبيل
شركة تنظيف بالاحساء
شركة قمة الدقة للخدمات المنزلية
ReplyDeleteشركة امست للتنظيف بالخبر
شركة مكافحة حشرات بالدمام
ReplyDeletehttps://khalejmovers.com
شركة نقل عفش من الرياض الى دبي
شركة نقل عفش من الرياض الى الاردن
ارخص شركة نقل عفش بجدة
افضل شركة نقل عفش بجدة
vé tết 2019 đi hà nội
ReplyDeletevé tết 2019 đi đồng hới
vé tết 2019 đi buôn mê thuột
vé tết 2019 đi nha trang
vé tết 2019 đi hải phòng
I am read your article and it’s helped me a lot, thank you so much for share this wonderful article, I really like to read this type of blog, keep sharing this type of useful information, I am suggest to my all contact to visit this blog and collect this helpful information, If any one searching website designing & development company in Delhi please visit my website, we are do for you any think like website build PPC service and many more so don’t waste your time and come on my website and grow more your business, Thank you so much for read my comment. Ecommerce Website Designing Company in Delhii
ReplyDeleteThis was be great I will read your blog properly, thank you so much for share this valuable information, I am enjoy to read this, it’s provided me lot of information, if any one grow up looking so please visit me website and I am share for you some tips so you will go and grow up your looks, thank you so much for read my comment.
ReplyDeleteLifestyle Magazine India
Rice Bags Manufacturers
ReplyDeletePouch Manufacturers
wall putty bag manufacturers
we have provide the best ppc service.
ReplyDeleteppc services in gurgaon
website designing company in Gurgaon
PPC company in Noida
we have provide the best fridge repair service.
ReplyDeletefridge repair in faridabad
Videocon Fridge Repair in Faridabad
Whirlpool Fridge Repair in Faridabad
Washing Machine Repair in Noida
godrej washing machine repair in noida
whirlpool Washing Machine Repair in Noida
IFB washing Machine Repair in Noida
LG Washing Machine Repair in Noida
Bali Honeymoon Packages From Delhi
ReplyDeleteBali Honeymoon Packages From Chennai
Hong Kong Packages From Delhi
Europe Packages from Delhi
Bali Honeymoon Packages From Bangalore
Bali Honeymoon Packages From Mumbai
Maldives Honeymoon Packages From Bangalore
travel company in Delhi
عالميه الدمام- 0542613483 - افضل شركات نقل العفش بالمنطقه الشرقيه شركة نقل عفش بالجبيل
هل تبحث عن شركة مناسبة للقيام بنقل عفش منزلك، هل تخشى من تجارب الأصدقاء المؤلمة مع شركات نقل العفش؟ شركة نقل عفش بالقطيف
لا تقلق عزيزي العميل، فأنت الآن في المكان الصحيح، حيث جاءت إليك شركة نقل عفش بالدمام شركة نقل اثاث بالخبر
يمكن تعريف الشحن المحدود الذي تقدمه شركه نقل اثاث بالدمام بكونه ما يقتصر على نقل ما قد يحتاجه العميل من أثاث كالأجهزة الكهربائية أو الأثاث الخشبية حتى وإن كان لقطع غيرة ومدودة منه. شركة نقل عفش بالخبر
ReplyDeleteنقل عفش بالخبر
شركة نقل عفش فى بالخبر
وجدير بالذكر أنه بعد الرفع يقوم العمال بتركيب الأثاث كما كان شركات نقل العفش بالخبر
شركتنا شركة نقل اثاث بالجبيل الأفضل كونها تنظم من عملها، وتنظم من عمالتها، فكل عامل له عمل مخصص يقوم به. نقل عفش بالدمام
ReplyDeleteنقل اثاث بالدمام
نقل عفش بالاحساء
لن تجد أجدر من شركه نقل عفش بالدمام قادرة على إتمام تلك المهمة حيث ثقة عملائها الكرام على المحك ولن تقبل تحت أي حال من الأحوال أن يخيب ظن العملاء نقل اثاث بالاحساء
شركة نقل عفش بالدمام
ReplyDeleteعالميه الدمام- 0542613483 - افضل شركات نقل العفش بالمنطقه الشرقيه شركة نقل اثاث بالدمام
ارخص شركة نقل اثاث بالدمام
شركة نقل اثاث بالجبيل
أن الشركة تتمتع بالالتزام التام بمواعيدها، فلا تعمل على مخالفتها تحت أي ظرف من الظروف وهذا بداية من عملية الاتصال وحتى إنهاء الخدمة تمامًا، كما أن فريق العمل ذو حجم كبير نسبيًا نقل عفش بالخبر
شركة نقل عفش بالجبيل
شركة نقل عفش بالجبيل
انوار طيبة أفضل شركة نظافة بالدمام متخصصة في مجال التنظيف بالدمام والمناطق المجاورة فنحن شركة تنظيف مكيفات بالدمام نقوم أيضاً بتنظيف (فلل– شقق- منازل- بيوت- المجالس- العمائر- الشركات – المطاعم – الفنادق- المحال التجارية) وجميع الأماكن التي تحتاج للتنظيف، وتقوم الشركة بتنظيف منزلك بأحدث الماكينات شركة تنظيف مكيفات بالدمام
ReplyDeleteشركة تنظيف مكيفات بالخبر
شركة تنظيف بالخبر تقدم أسعار مميزة لعملائها فهي أرخص شركة تنظيف مكيفات حيث تقوم بتنظيف المنازل والشقق والفلل والكنب والسجاد والمسابح والمدارس والمساجد والخزانات بالدمام و بالخبر و بالجبيل و بالقطيف تستخدم أجود أنواع المنظفات فهي افضل شركة نظافة بالخبر شركة غسيل مكيفات بالدمام
شركة تنظيف مكيفات بالقطيف
مؤسسة انوار طيبة-ارخص شركة تنظيف مكيفات بالقطيف والدمام والجبيل – افضل شركة تنظيف مكيفات السبلت بالدمام والقطيف، وتنظيف وصيانة وغسيل المكيفات سبليت ومركزية ومخفي وكاست ودولابي وشباك وتركيب جميع المكيفات شركتنا افضل شركة غسيل مكيفات بالدمام والجبيل تتعامل معكم شركة تنظيف مكيفات برأس تنورة
شركة تنظيف كنب بالدمام عندما تريد نظافه الكنب الموجود بمنزلك لاتنزعج اليك أفضل شركه تنظيف مكيفات بالدمام باحدث المكينات وافضل طرق التنظيف افضل شركة تنظيف كنب بالدمام نحن بعون الله من اكبر شركات التنظيف الكنب والمجالس بالدمام والخبر والقطيف والجبيل متخصصون فى مجال تنظيف جميع الاقمشه من ستائر ومجالس شركة تنظيف كنب بالدمام
ReplyDeleteشركة غسيل كنب بالدمام
افضل شركة تنظيف بالدمام و بالخبر ارخص الاسعار ، لنظافة المنازل و الشقق اهمية كبيرة في صحة الاسرة ، ولذلك اخترنا في الوطنية للنظافة بالمنطقة الشرقية افضل شركة تنظيف بالدمام و بالخبر ان نقدم لاهل الدمام والخبر خدمات تنظيف شاملة مع التعقيم لكافة مكونات المنزل العصري من اثاث او مفروشات او حمامات و مطابخ وتنظيف سيراميك وجلى بلاط شركة تنظيف كنب بالقطيف
شركة مكافحة حشرات بالخبر تقدم لكم العديد من الخدمات المميزة، حيث أن الشركة تستطيع مكافحة النمل الابيض بالقطيف بالإضافة إلى كافة أنواع الحشرات الأخرى بكل سهولة وبأحدث الإمكانيات مثل مكافحة البق بالقطيف ومكافحة الصراصير بالقطيف ومكافحة الصراصير بالقطيف ولها فروع مثل شركة مكافحة حشرات بالدمام شركة مكافحة حشرات بالقطيف
ReplyDeleteشركة مكافحة حشرات بالدمام. ان شركة مكافحة حشرات بالدمام تعلم جيدا ان الحشرات من أكثر الكائنات الحية انتشارا وتواجد على سطح الأرض حيث انها تعيش وتتكيف في المناخات المختلفة وتعرف شركة رش مبيدات بالدمام ان بعض الحشرات يعيش في جميع الاماكن فبعض الحشرات تستطيع الطيران فذلك يجعلها تنجو ولكن تفضي عليها من خلال افضل شركة مكافحة حشرات بالمنطقة الشرقية ، شركة الشرق الاوسط للنظافة ومكافحة الحشرات شركة مكافحة حشرات بالخبر
شركة مكافحة حشرات بالدمام
شركة مكافحة حشرات برأس تنورة
ان حشرة البق تشكل خطورة كبيرة علي المنازل وحصوصا الاطفال لذلك يمكنك ايجاد الحل الامثل من خلال شركة مكافحة البق بالدمام حيث تضم الشركة افضل الخبراء فهي افضل شركة مكافحة البق بالدمام شركة مكافحة البق بالدمام
ReplyDeleteشركة مكافحة البق بالخبر
شركة مكافحة النمل الابيض بالدمام
افضل شركة مكافحة النمل الابيض بالقطيف شركة انوار طيبة ونصلك اينما كنت نستخدم افضل المبيدات للقضاء علي الحشرات النمل والصراصير وبق الفراش والوزع والنمل الابيض وجميع الحشرات الزاحفة ,مكافحة جميع انواع الحشرات باستخدام افضل المبيدات المستوردة والمحلية لضمان القضاء علي الحشرات مع الضمان وخصومات هائلة شركة مكافحة النمل الابيض بالقطيف
شركات مكافحة حشرات ورش مبيدات بالدمام هل تبحث عن شركة مكافحة حشرات بالسعودية هل لديك نمل في المطبخ او حشرة البق في الخشب؟ هل عندك صراصير او نمل او فئران وتفسد عليك حياتك في منزلك او شركتك؟ لا تقلق فهناك العديد من شركات مكافحة الحشرات في السعودية وأيضا يوجد العديد من شركة رش مبيدات ومكافحة الحشرات بالدمام شركة رش مبيدات بالدمام
قبطان الخليج -0504353061-يُعد الأثاث من أكثر الأشياء التي تحتاج إلى حرص ودقة بالغة عند القيام بنقلها شركة نقل عفش بالظهران
ReplyDeleteتحرص على تقديم الضمان اللازم عن العمل الذي تقوم به لعملائها الكرام، فالضمان بدوره يطمئن العميل وفي النفس الوقت يضمن مصداقية الشركة شركة نقل اثاث بالظهران
شركة نقل اثاث بالخبر
ReplyDeleteدور شركة نقل أثاث بالقطيف في عملية نقل العفش شركة نقل عفش بالخبر
شركة نقل اثاث بالقطيف
أن العشوائية والعمل بدون تخطيط ووعي يكون مصيرهُ النهائي الفشل التام لا محالة من ذلك، لذلك فقد عمدت شركة نقل عفش بالخبر على أن تعمل وفقًا لاستراتيجية مُحددة شركة نقل عفش بالقطيف
شركة نقل اثاث برأس تنورة
يمكن تعريف الشحن المحدود الذي تقدمه شركه نقل اثاث بالدمام بكونه ما يقتصر على نقل ما قد يحتاجه العميل من أثاث كالأجهزة الكهربائية أو الأثاث الخشبية حتى وإن كان لقطع غيرة ومدودة منه. شركة نقل عفش بالدمام
ReplyDeleteشركة نقل اثاث بالدمام
فريق عمل شركة نقل عفش بالدمام نعرف جميعًا أن موظفي وعُمال الشركة هم الأيد المُحركة لها، والتي تلعب الدور الأكبر في مدى نجاحها واستمراره أرخص شركة نقل عفش بالدمام
ان حشرة البق تشكل خطورة كبيرة علي المنازل وحصوصا الاطفال لذلك يمكنك ايجاد الحل الامثل من خلال شركة مكافحة البق بالدمام حيث تضم الشركة افضل الخبراء فهي افضل شركة مكافحة البق بالدمام شركة رش حشرات بالدمام
ReplyDeleteشركة مكافحة حشرات بالدمام
شركة مكافحة حشرات بالخبر تقدم لكم العديد من الخدمات المميزة، حيث أن الشركة تستطيع مكافحة النمل الابيض بالقطيف بالإضافة إلى كافة أنواع الحشرات الأخرى بكل سهولة وبأحدث الإمكانيات مثل مكافحة البق بالقطيف ومكافحة الصراصير بالقطيف ومكافحة الصراصير بالقطيف ولها فروع مثل شركة مكافحة حشرات بالدمام شركة مكافحة حشرات بالخبر
شركة مكافحة البق بالدمام
شركة عزل اسطح بالدمام
ReplyDeleteعزيزي العميل نرحب بكم في شركة كشف تسربات المياه بالجبيل هل تعاني من إرتفاع ... شركة كشف تسربات المياه بالخبر شركه تسربات شركة كشف تسربات المياه بالجبيل
شركة كشف تسربات المياه بالخبر
هل تعبت عن البحث على شركة كشف تسربات المياه بالجبيل انتا الان مع شركة الافضل ... شركة كشف تسربات المياه بالدمام هى واحده من افضل الشركات شركة كشف تسربات المياه بالدمام
شركة تنظيف خزانات بالدمام
ReplyDeleteالتطور المستمر للشركة سواء من الناحية التكنولوجية أو الميدانية فكلاً منهما يعطي فائدة كبرى للأخرى، حيث تجد أن التكنولوجيا الحديثة التي تستخدمها شركة تنظيف خزانات بالدمام بالمعدات والأجهزة سهلت الأمر كثيراً في ميدان العمل عند تنظيف الخزانات شركة عزل خزانات بالدمام
شركة تنظيف خزانات بالخبر
مراعاة الشركة للمعايير والمقاييس الخاص بالسلامة لإعطاء أفضل النتائج، وما كان لنا سوى أن نهتم بذكر تلك النقاط عن كيفية عمل شركة غسيل خزانات بالقطيف شركة تنظيف خزانات بالقطيف
This is the most supportive blog which I have ever observed.
ReplyDeleteJava Training in Bangalore
Ui Development Training in Bangalore
Thank you so much for this excellent Post and all the best for your future. I hope you and we will be sharing more thoughts and keep writing more like this one.
ReplyDeleteoffice.com/setup
mcafee.com/activate
trung tâm tư vấn du học canada vnsava
ReplyDeletecông ty tư vấn du học canada vnsava
trung tâm tư vấn du học canada vnsava uy tín
công ty tư vấn du học canada vnsava uy tín
trung tâm tư vấn du học canada vnsava tại tphcm
công ty tư vấn du học canada vnsava tại tphcm
điều kiện du học canada vnsava
chi phí du học canada vnsava
#vnsava
@vnsava
ninonurmadi.com
ReplyDeleteninonurmadi.com
ninonurmadi.com
ninonurmadi.com
ninonurmadi.com
ninonurmadi.com
ninonurmadi.com
ninonurmadi.com
ninonurmadi.com
Wonderful blog. Keep on blogging to get new information.
ReplyDeletehow to increase business growth
importance of ai
need of artificial intelligence
why is python so popular
importance of cloud computing
oracle interview questions for experienced