﻿<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Дневна доза нонсенс... &#187; Dev</title>
	<atom:link href="http://dailyffs.com/category/dev/feed/" rel="self" type="application/rss+xml" />
	<link>http://dailyffs.com</link>
	<description>Софтуерно-инженерна му работа</description>
	<lastBuildDate>Tue, 03 Jan 2012 01:34:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Network of Things</title>
		<link>http://dailyffs.com/2011/network-of-things/</link>
		<comments>http://dailyffs.com/2011/network-of-things/#comments</comments>
		<pubDate>Wed, 07 Dec 2011 17:32:17 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[embedded]]></category>
		<category><![CDATA[НеБългария]]></category>
		<category><![CDATA[Нонсенс]]></category>
		<category><![CDATA[ericsson]]></category>
		<category><![CDATA[lte]]></category>
		<category><![CDATA[network of things]]></category>
		<category><![CDATA[telia]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=967</guid>
		<description><![CDATA[Ако преди 20 години малко хора са си представяли, че от WWW ще произлезе нещо огромно и ако преди 10 години малко хора са си представяли, че ще браузват интернет от телефоните си, то не е трудно да си представим колко малко хора си представят, че след 20 години хладилниците и пералните ни ще си комуникират по между си.<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/network-of-things/' addthis:title='Network of Things '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<h2>50 000 000 000</h2>
<p>Ако преди 20 години малко хора са си представяли, че от WWW ще произлезе нещо огромно и ако преди 10 години малко хора са си представяли, че ще браузват интернет от телефоните си, то не е трудно да си представим колко малко хора си представят, че след 20 години хладилниците и пералните ни ще си комуникират по между си.</p>
<p>Ериксън се опитва да натрапи тази идея:</p>
<p><iframe src="http://www.youtube.com/embed/Hc-l_BbGpjw" frameborder="0" width="560" height="315"></iframe></p>
<p>И най-вероятно това ще се случи.</p>
<p>2050 година, 50 милиарда устройства свързани в мрежа, 10% от общия трафик на данни ще е генериран от хора (останалото от машини), експоненциален ръст на обмена на данни всяка година, хладилникът и пералнята ви си говорят&#8230; think about it.</p>
<p>В момента естествено сме относително далеч от това. Bandwidth-a още е много малък, за да може това да се реализира.</p>
<h2>LTE</h2>
<p><a href="http://en.wikipedia.org/wiki/3GPP_Long_Term_Evolution">Long Term Evolution</a> или алтернатива на WiMax за 4G свързаност. Пълен дуплекс с времеделене (time-division) &#8211; два канала за пренос на данни вървящи паралелно, 300Mbit/s down-link.</p>
<p>Първият 4G базиран на LTE е баш в Швеция, оператора се казва Telia&#8230; и кой друг освен Ериксън може да е изработил мрежата им <img src='http://dailyffs.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .<br />
<iframe src="http://www.youtube.com/embed/LvINMnhotKc" frameborder="0" width="560" height="315"></iframe></p>
<p>Btw, ако спрете клипчето на 1:01 минута, ще видите че това на екрана е media player&#8230; it&#8217;s ALL LIES!</p>
<h2>Battery</h2>
<p>Другата голяма спънка да не се замеряме с 4G телефони в момента са батериите. Скоростния обмен на данни харчи ток. Доста ток.</p>
<p><a href="http://dailyffs.com/wp-content/uploads/2011/12/ancient_aliens_battery_meme.jpg"><img class="aligncenter size-medium wp-image-970" title="ancient_aliens_battery_meme" src="http://dailyffs.com/wp-content/uploads/2011/12/ancient_aliens_battery_meme-300x261.jpg" alt="" width="300" height="261" /></a></p>
<p>За това и няма много телефони, които да са с 4G&#8230; но скоро идват &#8211; <a href="http://www.telia.se/privat/katalog/VisaProdukt.do?productRef=/privat/mobilt/mobiltelefoner/samsung/samsung-galaxy-sii-lte.product">Samsung Galaxy S2 LTE</a> &#8230; в Швеция. В Бг не знам.</p>
<p>Батериите зависят от химиците. Ако сте химик, моля, побързайте да направите някоя по-сносна батерия <img src='http://dailyffs.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Това са парчетата от пъзела. Бъдещето звучи яко, а <img src='http://dailyffs.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/network-of-things/' addthis:title='Network of Things '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2011/network-of-things/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Нуждата от многоядрени процесори</title>
		<link>http://dailyffs.com/2011/the-need-of-multicore-cpu/</link>
		<comments>http://dailyffs.com/2011/the-need-of-multicore-cpu/#comments</comments>
		<pubDate>Tue, 22 Nov 2011 14:02:31 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[embedded]]></category>
		<category><![CDATA[Нонсенс]]></category>
		<category><![CDATA[cpu]]></category>
		<category><![CDATA[multicore]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=959</guid>
		<description><![CDATA[Процесор с честота 192GHz звучи като решение на изначалния проблем - Защо да не си караме с едноядрен процесор на супер висока честота?<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/the-need-of-multicore-cpu/' addthis:title='Нуждата от многоядрени процесори '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<h2><img class="aligncenter" src="http://25.media.tumblr.com/tumblr_ll5jrhN7Um1qzo8p7o1_400.png" alt="" width="276" height="347" /><br />
Част I</h2>
<h3>Защо аджеба имаме многоядрени процесори в стандартните персонални компютри?</h3>
<p>Не е защото програмите са супер добри в изпълнението на паралелни задачи. Програмите в обикновените компютри не са добри в изпълнението на паралелни задачи, защото хората, които ги пишат рядко измислят паралелни алгоритми за решаването на даден проблем.</p>
<p>Да вземем например процесор с 64 ядра. Всъщност дори и с 64 ядра&#8230; имаме 1 шина (северния мост), за достъп до паметта. Как 64 ядра могат ефективно да пишат и четата от паметта? Да не говорим за кеш кохийранс и потенциалните проблеми породени от <a href="http://en.wikipedia.org/wiki/False_sharing">false sharing-a</a>.</p>
<p>Проблемът на многоядрените процесори са хората-мислещи-последователно-вместо-паралелно-защото-така-са-свикнали и достъпът до споделени ресурси. 64 ядра vs. една памет, един кеш, един кернел&#8230; и още много неща, които са по едно. Как 64 неща могат да работят ефективно с едно нещо едновремено и да са в синхрон &#8211; това е проблемът.</p>
<h3>Защо нямаме едно ядро, което да върви на 64*3GHz?</h3>
<p>Много уместен въпрос! Процесор с честота 192GHz звучи като решение на изначалния проблем &#8211; Защо да не си караме с едноядрен процесор на супер висока честота?</p>
<p>well&#8230;</p>
<ul>
<li>Скоростта на светлината във вакуум е ~300 000 000 м/сек.</li>
<li>192GHz са 192 000 000 000 такта в секунда</li>
</ul>
<p>Простата сметка 300 000 000 / 192 000 000 000 = 1.5mm , показва че този процесор трябва да е голям около 1 милиметър (кв., куб.), за да може часовникът да разпространи сигнала си в него 192 милиарда пъти в секунда&#8230; и това са някакви груби, половинчати сметки. Това, което се опитвам да ви накарам да осъзнаете е че:</p>
<ol>
<li>Не може да поберете процесор в такова пространство.</li>
<li>Ако поберете процесор в такова пространство ще ви трябва нещо по-студено от течен азот за да го охладите. Ще ви трябва и малка електроцентралка, за да го захраните.</li>
<li>Ако успеете да намерите нещо по-бързо от светлината&#8230; good for you!</li>
</ol>
<h2>Част II</h2>
<p>Единственият начин да имаме повече изчислителна мощ със сегашните закони на физиката е като имаме повече изчислителни устройства, които работят паралелно. За това си купувате 2-4-8 ядрени процесори на ниска честота (2 GHz).</p>
<p>Но един процес винаги върви на едно ядро &#8211; т.е. ако имате един единствен процес и искате да върви бързо, тогава ви трябва едно единствено ядро на висока честота (4 GHz например, вместо 2GHz). Това е миниатюрна частичка от един друг голям проблем &#8211; Ако имате програма, която изчислява някакъв резултат за X секунди на процесор с 1 ядро, нямате гаранция че ако пуснете програмата на процесор с 8 ядра със същата честота, тя ще върви 8 пъти по-бързо. Нещо повече, вашата програма може да върви дори по-бавно от колкото на 4 ядра. Т.е. вашият софтуер може да не се скалира добре върху многоядрена архитектура.</p>
<p>Това е като да си хирург в 13-ти век&#8230; взимаш някакъв труп и пориш, и изучаваш, и не разбираш, и си блъскаш главата&#8230; и след 100-200 години вече всичко е ясно и човечеството вече знае как работи човешкото тяло.</p>
<p>Ние сме в 13-ти век <img src='http://dailyffs.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/the-need-of-multicore-cpu/' addthis:title='Нуждата от многоядрени процесори '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2011/the-need-of-multicore-cpu/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Game of Life (javascript + html5&#8242;s canvas)</title>
		<link>http://dailyffs.com/2011/game-of-life-javascript-html5/</link>
		<comments>http://dailyffs.com/2011/game-of-life-javascript-html5/#comments</comments>
		<pubDate>Sun, 24 Jul 2011 20:55:57 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[game of life]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=907</guid>
		<description><![CDATA[Тези дни отново ме загриза съвестта, че не работя по някакъв сайд-проект - мой собствен или open source и за това днес реших да почета и понапиша Game of Life.<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/game-of-life-javascript-html5/' addthis:title='Game of Life (javascript + html5&#8242;s canvas) '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p>Тези дни отново ме загриза съвестта, че не работя по някакъв сайд-проект &#8211; мой собствен или open source и за това днес реших да почета и понапиша <a href="http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">Game of Life</a>.</p>
<p>Оказа се доста прост алгоритъм с доста интересна история, която и сами може да си прочетете <img src='http://dailyffs.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Демо може да видите тук: <a href="http://dailyffs.com/life/">http://dailyffs.com/life/</a></p>
<p>Сорсът е тук: <a href="https://gist.github.com/1102964">https://gist.github.com/1102964</a></p>
<p>Коментарът към сорса от страна на @skanev е тук: <a href="https://twitter.com/skanev/status/95213748092026880">https://twitter.com/skanev/status/95213748092026880</a></p>
<p>Това, което искам да кажа в тази статия е, че колкото и да са бързи съвремените Javascript engine-и и колкото и разни светила и икони на браузър вендорите да се хвалят, че производителността скача многократно от версия до версия, това не значи че не може да забързате всичко още <del>малко</del> много. Цената на &#8222;забързването&#8220; е &#8222;угрозняване&#8220; и оптимизиране на кода. В моя конкретен случай &#8211; на една функция, която се вика 60000 пъти на преизчисление.</p>
<p>Въпросната фунцкия:</p>
<pre class="brush: jscript; title: ; notranslate">

function getLiveNeighbours(id, data) {
  var x = id % canvas.width;
  var y = parseInt(id / canvas.width);

  var cnt = 0;
  for (var i = -1; i &lt; 2; i++) {
    for (var j = -1; j &lt; 2; j++) {
      if ((i != 0 || j != 0) &amp;&amp;
        !(x+i &lt; 0 || x+i &gt;= canvas.width || y+j &lt; 0 || y+j &gt;= canvas.height) &amp;&amp;
        data.data[4*((y+j)*canvas.width+(x+i))] != THE_BLACK) {
        cnt++;
      }
    }
  }
  return cnt;
}
</pre>
<p>Простата оптимизация на кода включва:</p>
<ol>
<li>Премахване на извикването на функцията (тялото на функцията се ползва директно) &#8211; спестява 60000 извиквания и времето за изпълнение на една итерация пада от 500ms на 270ms</li>
<li>Заменяне на двата вложени цикъла проверяващи за броя на съседни клетки &#8211; от 270ms на 150ms</li>
<li>Опростяване на пресмятанията (премахване на умножения) &#8211; от 150ms на 60ms</li>
<li>Създаване на локални референции към често използваните данни (вместо постоянни извиквания от типа &#8222;obj.data&#8220; при изчисленията се създава и използва локална променлива) &#8211; от 60ms на 50ms</li>
</ol>
<pre class="brush: jscript; title: ; notranslate">
// (4)
var width = canvas.width*4;
var d = data.data;
var nd = newdata.data;
var cw = canvas.width;
var ch = canvas.height;
var base = 0;

for (var i = 0; i &lt; d.length/4; i++) {
  var x = i % cw;
  var y = parseInt(i / cw);

  var cnt = 0;
  // (1), (2), (3)
  if (x &gt; 0 &amp;&amp; d[base-4] != THE_BLACK) cnt++;
  if (x &lt; cw-1 &amp;&amp; d[base+4] != THE_BLACK) cnt++;
  if (x &gt; 0 &amp;&amp; y &gt; 0 &amp;&amp; d[base-4-width] != THE_BLACK) cnt++;
  if (y &gt; 0 &amp;&amp; d[base-width] != THE_BLACK) cnt++;
  if (x &lt; cw-1 &amp;&amp; y &gt; 0 &amp;&amp; d[base+4-width] != THE_BLACK) cnt++;
  if (x &gt; 0 &amp;&amp; y &lt; ch-1 &amp;&amp; d[base-4+width] != THE_BLACK) cnt++;
  if (y &lt; ch-1 &amp;&amp; d[base+width] != THE_BLACK) cnt++;
  if (x &lt; cw-1 &amp;&amp; y &lt; ch-1 &amp;&amp; d[base+4+width] != THE_BLACK) cnt++;
  ...
</pre>
<p>В крайна сметка производителността скочи 10 пъти, макар логиката на кода да изглежда по-зле от преди. Не, че преди изглеждаше много красива, но все пак <img src='http://dailyffs.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Разбира се има и още един доста по-умен начин за техническа оптимизация &#8211; Web Workers. Те са панацеята на всички проблеми, началото и края, давид и голиат, содом и гомор, ин и ян&#8230; за тях може да почетете тази статия -<a href="../2011/mandelbrot-web-workers/" rel="bookmark"> Mandelbrot + Web Workers</a></p>
<p><em>Забележка: </em></p>
<ul>
<li><em>става дума за проста техническа оптимизация на кода, а не за подобрения на алгоритъма!</em></li>
<li><em>вероятно оптимизациите в javascript engine-ите не се фокусират върху случаи на извикване на функция 60 хиляди пъти&#8230; а би трябвало.</em></li>
</ul>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/game-of-life-javascript-html5/' addthis:title='Game of Life (javascript + html5&#8242;s canvas) '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2011/game-of-life-javascript-html5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Прозрение</title>
		<link>http://dailyffs.com/2011/%d0%bf%d1%80%d0%be%d0%b7%d1%80%d0%b5%d0%bd%d0%b8%d0%b5/</link>
		<comments>http://dailyffs.com/2011/%d0%bf%d1%80%d0%be%d0%b7%d1%80%d0%b5%d0%bd%d0%b8%d0%b5/#comments</comments>
		<pubDate>Sat, 23 Jul 2011 12:17:32 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=904</guid>
		<description><![CDATA[Преди няколко дни започнах да пиша малко плъгинче (първия ми плъгин акшуъли) за Django, което да филтрира браузъри в зависимост от useragent-а им. Идеята ми беше филтрирането да става в зависимост от версията на браузъра&#8230; идея, която работеше преди 5 години. Останах си с тази идея до момента, в който видях няколко useragent-a от мобилни [...]<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/%d0%bf%d1%80%d0%be%d0%b7%d1%80%d0%b5%d0%bd%d0%b8%d0%b5/' addthis:title='Прозрение '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p>Преди няколко дни започнах да пиша малко плъгинче (първия ми плъгин акшуъли) за Django, което да филтрира браузъри в зависимост от useragent-а им. Идеята ми беше филтрирането да става в зависимост от версията на браузъра&#8230; идея, която работеше преди 5 години. Останах си с тази идея до момента, в който видях няколко useragent-a от мобилни устройства и таблети. Накратко един с един нямат общо, но това което си остава при всички е версията на layout engine-a.</p>
<p>Това е хора. Забравете за IE X или Firefox Y и  т.н., това което ще направи сайта ви да работи на десктоп, телефон и таблет е версията на layout engine-a в комбинация с данните от тези таблички: <a href="http://en.wikipedia.org/wiki/Comparison_of_layout_engines_%28Cascading_Style_Sheets%29">http://en.wikipedia.org/wiki/Comparison_of_layout_engines_%28Cascading_Style_Sheets%29</a> и <a href="http://caniuse.com/">http://caniuse.com/</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/%d0%bf%d1%80%d0%be%d0%b7%d1%80%d0%b5%d0%bd%d0%b8%d0%b5/' addthis:title='Прозрение '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2011/%d0%bf%d1%80%d0%be%d0%b7%d1%80%d0%b5%d0%bd%d0%b8%d0%b5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Upload на blob като файл чрез AJAX</title>
		<link>http://dailyffs.com/2011/upload-blob-as-file-ajax/</link>
		<comments>http://dailyffs.com/2011/upload-blob-as-file-ajax/#comments</comments>
		<pubDate>Thu, 14 Jul 2011 07:10:15 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[blob]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=888</guid>
		<description><![CDATA[Наскоро забелязах, че при изпращането на голям скрийншот в http://screenshoot.me се случват някакви неприятни неща. По-точно грешка 413 Request entity too large. Оказа се, че хостингът ми не позволява изпращане на POST заявки с параметри по-големи от 1-2мб. За сметка на това пък позволява качване на файлове до 20мб. До тук единственото нещо, което ме притесняваше е дали може да "симулирам" изпращане на файл чрез AJAX. Оказа се че може. FUCK YEAH!<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/upload-blob-as-file-ajax/' addthis:title='Upload на blob като файл чрез AJAX '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p><em>Заглавието и на мен не ми говори нищо, за това ще се опитам да обясня с прости думи казуса.</em></p>
<p>Наскоро забелязах, че при изпращането на голям скрийншот в <a href="http://screenshoot.me">http://screenshoot.me</a> се случват някакви неприятни неща. По-точно грешка <em>413 Request entity too large</em>. Оказа се, че хостингът ми не позволява изпращане на POST заявки с параметри по-големи от 1-2мб. За сметка на това пък позволява качване на файлове до 20мб. До тук единственото нещо, което ме притесняваше е дали може да &#8222;симулирам&#8220; изпращане на файл чрез AJAX. Оказа се че може. FUCK YEAH!</p>
<p>Всъщност може да си префасонирате цялата заявка както ви скимне, което е много готино и същевремено много жалко, защото десетките хиляди фронт-енд дивелъпъри, ползващи jQuery и нямащи понятие от javascript никога няма да узнаят за този факт. <em></em></p>
<p><em>Вероятно бъркам, просто се опитвам да си обясня защо на всяко интервю винаги питат &#8222;а ти с jQuery знаеш ли как да работиш&#8220; все едно манюъла е 500 страници и ти трябва висше <img src='http://dailyffs.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</em></p>
<p>Та реших да разширя <a href="http://www.openjs.com/scripts/jx/">леката библиотечка</a> (&#8222;парче код&#8220; е правилната дума), която ползвам за AJAX обаждания и съответно резултата е тук &#8211; <a href="https://github.com/lucho870601/ajax-blob-upload">https://github.com/lucho870601/ajax-blob-upload</a></p>
<p>Накратко:</p>
<pre class="brush: jscript; title: ; notranslate">
jx.generateBoundary = function(fieldsData) { // Функция, която генерира уникален разделител валиден за всеки фрагмент
  var boundary = parseInt(Math.random()*Math.pow(10, 16)).toString(36) + '' + parseInt(Math.random()*Math.pow(10, 16)).toString(36);
  for (var i = 0; i &lt; fieldsData.length; i++) {
    if (fieldsData[i].indexOf(boundary) &gt; -1) {
      // generate new boundary and check all fields again
      boundary = parseInt(Math.random()*Math.pow(10, 16)).toString(36) + '' + parseInt(Math.random()*Math.pow(10, 16)).toString(36);
      i = 0;
    }
  }
  return boundary;
};

jx.loadFile = function(url, fileData, fileName, callback, opt) {
  var http = this.init(); //The XMLHttpRequest object is recreated at every call - to defeat Cache problem in IE
  if(!http||!url) return;
  var parts = url.split('?');
  var url = parts[0];
  var parameters = parts[1] ? parts[1].split('&amp;') : [];

  var fieldsData = [fileData];
  for (var i = 0; i &lt; parameters.length; i++) {
    fieldsData.push(parameter[i][1]);
  }

  var boundary = this.generateBoundary(fieldsData);
  var body = '';
  for (var i = 0; i &lt; parameters.length; i++) {
    // строим фрагментите за данни
    var p = parameters[i].split('=');
    body += &quot;--&quot; + boundary + &quot;\r\n\
Content-Disposition: form-data; name='&quot;+p[0]+&quot;'\r\n\
\r\n\
&quot;+(p[1] || '')+&quot;\r\n&quot;;
  }

  // фрагмента за псевдо-файла
  body += &quot;--&quot; + boundary + &quot;\r\n\
Content-Disposition: form-data; name='&quot; + fileName + &quot;'; filename='&quot; + fileName + &quot;'\r\n\
Content-Type: application/octet-stream\r\n\
\r\n\
&quot;+ fileData + &quot;\r\n\
--&quot; + boundary + &quot;--\r\n&quot;;

  http.open(&quot;POST&quot;, url, true);
  http.setRequestHeader(&quot;Content-Type&quot;, &quot;multipart/form-data; boundary=&quot;+boundary);
  http.setRequestHeader(&quot;Content-Length&quot;, body.length);
  http.setRequestHeader(&quot;Connection&quot;, &quot;close&quot;);
  ...
  http.send(body);
};
</pre>
<p>&#8230; и получавате данните си като файл накрая.</p>
<p>Кофтито в цялата история е, че не мога да убедя браузъра ми да не слага &#8222;charset&#8220; и вероятно заради това blob-а пристига в съвсем друг вид. За това пък решението е доста лесно &#8211; кодиране на бинарните данни в base64. Неприятно е, че request-а ще набъбне с 1/3 повече и ще трябва да отворите и decode-нете файла сами. На теория декодирането на файла трябва да стане автоматично с <em>Content-Transfer-Encoding </em>директива, но на практика не стана <img src='http://dailyffs.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Удачно е да ползвате този подход не само при гореописания проблем, но и винаги, когато пращате индустриални количества бинарни данни, защото получаването на файл е по-бързо и ангажира по-малко ресурси отколкото получаването на данните като параметър.  Поне така ми се струва <img src='http://dailyffs.com/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> </p>
<p><a href="http://dailyffs.com/wp-content/uploads/2011/07/ajax.jpg"><img class="aligncenter size-full wp-image-895" title="ajax" src="http://dailyffs.com/wp-content/uploads/2011/07/ajax.jpg" alt="" width="300" height="404" /></a></p>
<p><em>П.П. Преди да имплементирам алтернативното решение се помъчих да увелича лимита на размера на POST заявките с конфигуриране на .htaccess и ini_set на разни магически PHP параметри, но непотръгна.</em></p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/upload-blob-as-file-ajax/' addthis:title='Upload на blob като файл чрез AJAX '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2011/upload-blob-as-file-ajax/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Software Engineering != Software Development</title>
		<link>http://dailyffs.com/2011/software-engineering-software-development/</link>
		<comments>http://dailyffs.com/2011/software-engineering-software-development/#comments</comments>
		<pubDate>Fri, 08 Jul 2011 14:27:51 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=875</guid>
		<description><![CDATA[Ще ви го повторя 50 пъти, пък дано отворите wikipedia най-накрая<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/software-engineering-software-development/' addthis:title='Software Engineering != Software Development '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p><strong>Ще ви го повторя 50 пъти, пък дано отворите wikipedia най-накрая</strong></p>
<pre class="brush: plain; title: ; notranslate">
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
</pre>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/software-engineering-software-development/' addthis:title='Software Engineering != Software Development '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2011/software-engineering-software-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mandelbrot + Web Workers</title>
		<link>http://dailyffs.com/2011/mandelbrot-web-workers/</link>
		<comments>http://dailyffs.com/2011/mandelbrot-web-workers/#comments</comments>
		<pubDate>Mon, 13 Jun 2011 19:28:20 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[mandelbrot]]></category>
		<category><![CDATA[webworkers]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=860</guid>
		<description><![CDATA[Обичам фрактална графика и поради липса на по-смислено занимание тези дни, реших да напиша визуализатор за Mandelbrot. Имплементацията ползва готините Web Workers, за да се справи с тоновете сметки и Canvas за да изобрази резултатът на екрана.

48 web worker-a се борят да запълнят 800х600 пиксела пространство и да си призная се справят по-добре от очакваното... е, все още си е бавно, но е 48 пъти по-добре отколкото без възможност за паралелно изпълнение на алгоритъма :D.<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/mandelbrot-web-workers/' addthis:title='Mandelbrot + Web Workers '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://dailyffs.com/mandelbrot/"><img class="aligncenter" title="Mandelbrot + Web Workers" src="http://screenshoot.me/Ao7vyS" alt="" width="531" height="422" /></a></p>
<p>Обичам фрактална графика и поради липса на по-смислено занимание тези дни, реших да напиша визуализатор за <a href="http://en.wikipedia.org/wiki/Mandelbrot_set">Mandelbrot</a>. Имплементацията ползва готините <a href="http://www.whatwg.org/specs/web-workers/current-work/">Web Workers</a>, за да се справи с тоновете сметки и <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html">Canvas</a> за да изобрази резултатът на екрана.</p>
<p>48 web worker-a се борят да запълнят 800х600 пиксела пространство и да си призная се справят по-добре от очакваното&#8230; е, все още си е бавно, но е 48 пъти по-добре отколкото без възможност за паралелно изпълнение на алгоритъма <img src='http://dailyffs.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> .</p>
<p><strong>Резултатът може да видите тук &#8211; <a href="http://dailyffs.com/mandelbrot/">http://dailyffs.com/mandelbrot/</a></strong></p>
<p><strong>А кодът е достъпен тук &#8211; <a href="https://gist.github.com/1023445">https://gist.github.com/1023445</a></strong></p>
<p><em>Забележка: работи само с Firefox, защото другите браузъри или нямат web workers или не поддържат предаването на по-сложни обекти от/към worker-ите. </em></p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/mandelbrot-web-workers/' addthis:title='Mandelbrot + Web Workers '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2011/mandelbrot-web-workers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Малко python benchmarking</title>
		<link>http://dailyffs.com/2011/python-hacks-benchmarking/</link>
		<comments>http://dailyffs.com/2011/python-hacks-benchmarking/#comments</comments>
		<pubDate>Fri, 10 Jun 2011 07:45:54 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[benchmark]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=838</guid>
		<description><![CDATA[Наскоро се сблъсках със следния казус:

Как най-ефективно да преубразувам списък от repr на двойки елементи в списък от двойки елементи (т.е. да eval-на всеки string в python-ски tuple)<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/python-hacks-benchmarking/' addthis:title='Малко python benchmarking '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p>Наскоро се сблъсках със следния казус:</p>
<p>Как най-ефективно да преобразувам списък от repr на двойки елементи в списък от двойки елементи (т.е. да eval-на всеки string в python-ски tuple). Пример:</p>
<pre class="brush: python; title: ; notranslate">

[&quot;('text1', 'text2')&quot;, &quot;('text3', 'text4')&quot;, ... &quot;('textn', 'textm')&quot;]
</pre>
<p>Ето и четирите начина, които тествах:</p>
<pre class="brush: python; title: ; notranslate">

from time import time
import re

def time_it(n, func, data):
 start = time()
 out = map(func, data)
 print 'time for case %d:' % n, time()-start
 return out

data = map(repr, zip(map(str, range(10**6)), map(str, range(10**6))))
out = []

# 1 - eval на всеки елемент
out.append(time_it(1, eval, data))

# 2 - премахване на ненужните символи
out.append(time_it(2, lambda x: x[2:-2].split('\', \''), data))

# 3 - match-ване на стойностите с регулярен израз за всеки елемент
pattern = re.compile(r'''\('(\w+)', '(\w+)'\)''')
out.append(time_it(3, lambda x: pattern.search(x).group(1, 2), data))

# 4 - match-ване на стойностите с регулярен израз върху всички елементи обединени в един string
pattern = re.compile(r&quot;'(\w+)'&quot;)
start = time()
res = pattern.findall(''.join(data))
out.append(zip(res[::2], res[1::2]))
print 'time for case 4:', time()-start

print 'are they all the same?', len(filter(lambda o: o != out[0], map(lambda x: map(tuple, x), out))) == 0
</pre>
<p>Ето и времената:</p>
<pre class="brush: plain; title: ; notranslate">

time for case 1: 15.3229999542
time for case 2: 2.14499998093
time for case 3: 1.76999998093
time for case 4: 1.20600008965
are they all the same? True
</pre>
<p>Познах им класацията по бързодействие още преди да ги напиша <img src='http://dailyffs.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Естествено, най-правилният начин е този, който първи идва в главата на човек &#8211; eval. За съжаление обаче, ще трябва доста да почакате! Дори и да се направите на хитри и да пробвате със следния код (който е още по-грозен от вариант номер 4)</p>
<pre class="brush: python; title: ; notranslate">

eval(repr(data).replace('&quot;', ''))
</pre>
<p>пак времето нужно за изпълнение е около 10 пъти повече от вариант номер 4.</p>
<p>Макар че четвъртият пример е най-ефективен, не го препоръчвам поради ред причини, но най-вече защото кодът не се ръководи по форматa на данните, а просто агрегира всичко, което е между кавички. За това пък третият вариант е доста близък по време до четвъртия и за разлика от него се ръководи по структурата на данните, не прави един огромен текстов низ и е доста по-кратък и разбираем. Вариант номер 2 го забравете, че съществува <img src='http://dailyffs.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Та, в заключение &#8211; гледайте да използвате по-рядко eval и да балансирате добре между разбираемост и бързодействие.</p>
<p><img class="aligncenter" title="chronos" src="http://www.chronos-historical.org/highway/images/logo.gif" alt="" width="240" height="232" /></p>
<p>P.S. Eval is Evil by default&#8230; so never use it for evaluating external code or else your program will execute someone else&#8217;s code <img src='http://dailyffs.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/python-hacks-benchmarking/' addthis:title='Малко python benchmarking '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2011/python-hacks-benchmarking/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Как работи един голям не-ентърпрайз софтуерен проект</title>
		<link>http://dailyffs.com/2011/how-does-disqus-work/</link>
		<comments>http://dailyffs.com/2011/how-does-disqus-work/#comments</comments>
		<pubDate>Sun, 05 Jun 2011 13:31:10 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[Haystack]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=827</guid>
		<description><![CDATA[Преди 2 седмици попаднах на това видео от PyCon 2011, в което създателите на едно от най-големите Django приложения - Disqus, разказват как работи то. Disqus е embeddable платформа за коментиране, която има над 500 милиона посетители дневно. Само поради този факт си струва да изгледате видеото...<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/how-does-disqus-work/' addthis:title='Как работи един голям не-ентърпрайз софтуерен проект '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p>Преди 2 седмици попаднах на това видео от PyCon 2011, в което създателите на едно от най-големите Django приложения &#8211; <a href="http://disqus.com/">Disqus</a>, разказват как работи то. Disqus е embeddable платформа за коментиране, която има над <strong>500 милиона уникални посетители</strong> месечно. Само поради този факт си струва да изгледате видеото&#8230; освен това ползват и разработват доста хитри туулове, с които е добре да се запознае човек.</p>
<p><embed type="application/x-shockwave-flash" width="480" height="390" src="http://blip.tv/play/g4Vigqr8YwI" allowscriptaccess="always" allowfullscreen="true"></embed></p>
<p>Другото интересно нещо, което намерих е fork на <a href="http://haystacksearch.org/">haystack</a> със spatial support &#8211; <a href="https://github.com/dannercustommade/django-haystack">https://github.com/dannercustommade/django-haystack</a></p>
<p><del>Точно си мислих да започна да пиша разширение за haystack, което да поддържа новите spatial функции в solr и се оказа, че съм закъснял с 2 месеца. Карай. </del></p>
<p>Оказа се, че плъгинът не е напълно завършен и spatial функциите не работят с последната версия на solr, така че ще го форкна и ще пробвам да го пооправя.</p>
<p><em>п.п. haystack е django плъгин за работа със <a href="http://lucene.apache.org/solr/">solr</a> и други full-text search engines.</em></p>
<p><em><img class="aligncenter" src="https://img.skitch.com/20110221-km134kgnbcs4qt94g16d2w1ggn.png" alt="" width="328" height="120" /><br />
</em></p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/how-does-disqus-work/' addthis:title='Как работи един голям не-ентърпрайз софтуерен проект '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2011/how-does-disqus-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Тернарен-if в Python</title>
		<link>http://dailyffs.com/2011/ternary-if-python/</link>
		<comments>http://dailyffs.com/2011/ternary-if-python/#comments</comments>
		<pubDate>Thu, 26 May 2011 22:02:22 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=821</guid>
		<description><![CDATA[В първите 2 минути като видях този начин на изписване бях доста учуден. Вероятно всеки би бил и вероятно този запис е в пъти по-нечетим от стандартния тернарен-if, но въпреки всичко се доближава повече до обикновения тернарен оператор и сигурно е по-лесен за възприемане от хора с опит в други езици.<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/ternary-if-python/' addthis:title='Тернарен-if в Python '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p>Както сигурно знаете, в Python писането на <del>тернарен условен преход</del> ternary-if е доста дълъг процес</p>
<pre class="brush: python; title: ; notranslate">

&lt;cmd A&gt; if &lt;condition&gt; else &lt;cmd B&gt;
</pre>
<p>докато във всички останали езици обикновено е</p>
<pre class="brush: jscript; title: ; notranslate">

&lt;condition&gt; ? &lt;cmd A&gt; : &lt;cmd B&gt;
</pre>
<p>Това несъмнено е по-грозен и труден за четене начин, но всички са му свикнали &#8211; условие, първа команда, втора команда.</p>
<p>Наскоро видях един друг похват използван в два различни плъгина за Django (единият беше south, другият не помня).</p>
<pre class="brush: python; title: ; notranslate">

&lt;condition&gt; and &lt;cmd A&gt; or &lt;cmd B&gt;
</pre>
<p>В първите 2 минути като видях този начин на изписване бях доста учуден. Вероятно всеки би бил и вероятно този запис е в пъти по-нечетим от стандартния тернарен-if, но въпреки всичко се доближава повече до обикновения тернарен оператор и сигурно е по-лесен за възприемане от хора с опит в други езици.</p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/ternary-if-python/' addthis:title='Тернарен-if в Python '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2011/ternary-if-python/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

