擅长:python、mysql、java
<p>区别在于三个方面的结合:</p>
<ol>
<li><p>你只是没有少做那么多工作。您的测试用例包括测试大量的小数字,其中测试“从2到平方根的所有数字”和测试“从2到平方根的所有素数”之间的区别并没有那么大。你的“平均情况”大约是范围的中点,50000,223.6的平方根,这意味着测试48个素数,或者测试222个数,如果这个数是素数,但是<em>大多数</em>数不是素数,<em>大多数</em>数至少有一个小因子(证明作为练习),因此,你短路了,实际上不测试任何一组中的大多数数字(如果有一个系数低于8,适用于所有数字的77%,那么你通过限制自己使用素数,节省了<em>可能</em>两次测试)</p>
</li>
<li><p>每次都要对<code>mem</code>进行切片,即使没有使用所有的值(如前所述,对于非素数,您几乎从来没有使用过),也会急切地、完整地执行该操作。这并不是一个巨大的成本,但是,跳过非素数并没有带来巨大的节约,因此它可能会吃掉从其他优化中获得的少量节约</p>
</li>
<li><p>(你发现了这一个,很好的展示)你的素数切片需要测试的素数的<em>个数</em>等于要测试的素数的平方根,而不是所有的素数都小于要测试的素数的平方根。因此,实际上您执行了相同数量的测试,只是使用了不同的数字(其中许多素数大于平方根,绝对不需要测试)</p>
</li>
</ol>
<p>旁注:</p>
<p>你的前期测试实际上并没有为你节省很多工作;您在循环中重复这两个测试,因此当数字为素数时,这两个测试都是徒劳的(您测试了两次)。你对5的可除性的测试是毫无意义的<code>% 10</code>比<code>% 5</code>快不了多少(计算机无论如何都不以10为基数运行),而<code>if not p % 5:</code>是一种更快、更直接、更完整的测试方法(您的测试不识别10的倍数,只是5的倍数,<em>不是10的倍数)</p>
<p>这些测试也是错误的,因为它们不排除基本情况(它们说2和5不是素数,因为它们分别可被2和5整除)</p>